LCOV - code coverage report
Current view: top level - EnergyPlus - ExternalInterface.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 763 1438 53.1 %
Date: 2024-08-23 23:50:59 Functions: 16 21 76.2 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // FMI-Related Headers
      49             : extern "C" {
      50             : #include <BCVTB/utilSocket.h>
      51             : #include <BCVTB/utilXml.h>
      52             : #include <FMI/main.h>
      53             : }
      54             : 
      55             : // C++ Headers
      56             : #include <string>
      57             : #include <vector>
      58             : 
      59             : // ObjexxFCL Headers
      60             : #include <ObjexxFCL/Array.functions.hh>
      61             : #include <ObjexxFCL/string.functions.hh>
      62             : 
      63             : // EnergyPlus Headers
      64             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      65             : #include <EnergyPlus/DataEnvironment.hh>
      66             : #include <EnergyPlus/DataIPShortCuts.hh>
      67             : #include <EnergyPlus/DataStringGlobals.hh>
      68             : #include <EnergyPlus/DataSystemVariables.hh>
      69             : #include <EnergyPlus/DisplayRoutines.hh>
      70             : #include <EnergyPlus/EMSManager.hh>
      71             : #include <EnergyPlus/ExternalInterface.hh>
      72             : #include <EnergyPlus/FileSystem.hh>
      73             : #include <EnergyPlus/GlobalNames.hh>
      74             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      75             : #include <EnergyPlus/OutputProcessor.hh>
      76             : #include <EnergyPlus/RuntimeLanguageProcessor.hh>
      77             : #include <EnergyPlus/ScheduleManager.hh>
      78             : #include <EnergyPlus/UtilityRoutines.hh>
      79             : 
      80             : namespace EnergyPlus::ExternalInterface {
      81             : 
      82             : // Module containing the routines dealing with the BCVTB interface
      83             : 
      84             : // MODULE INFORMATION:
      85             : //       AUTHOR         Michael Wetter
      86             : //       DATE WRITTEN   2Dec2007
      87             : //       MODIFIED       Rui Zhang July 2009
      88             : //       MODIFIED       Thierry S. Nouidui 2011
      89             : 
      90             : // PURPOSE OF THIS MODULE:
      91             : // To encapsulate the data and routines required to interface
      92             : // the Building Controls Virtual Test Bed (BCVTB) and FunctionalMockupUnits (FMU)
      93             : 
      94             : // REFERENCES:
      95             : // http://simulationresearch.lbl.gov/bcvtb
      96             : // http://www.modelisar.com
      97             : 
      98     1946046 : void ExternalInterfaceExchangeVariables(EnergyPlusData &state)
      99             : {
     100             : 
     101             :     // SUBROUTINE INFORMATION:
     102             :     //       AUTHOR         Michael Wetter
     103             :     //       DATE WRITTEN   2Dec2007
     104             : 
     105             :     // PURPOSE OF THIS SUBROUTINE:
     106             :     // Exchanges variables between EnergyPlus and the BCVTB socket.
     107             : 
     108     1946046 :     if (state.dataExternalInterface->GetInputFlag) {
     109         795 :         GetExternalInterfaceInput(state);
     110         795 :         state.dataExternalInterface->GetInputFlag = false;
     111             :     }
     112             : 
     113     1946046 :     if (state.dataExternalInterface->haveExternalInterfaceBCVTB || state.dataExternalInterface->haveExternalInterfaceFMUExport) {
     114           0 :         InitExternalInterface(state);
     115             :         // Exchange data only after sizing and after warm-up.
     116             :         // Note that checking for ZoneSizingCalc SysSizingCalc does not work here, hence we
     117             :         // use the KindOfSim flag
     118           0 :         if (!state.dataGlobal->WarmupFlag && (state.dataGlobal->KindOfSim == Constant::KindOfSim::RunPeriodWeather)) {
     119           0 :             CalcExternalInterface(state);
     120             :         }
     121             :     }
     122             : 
     123     1946046 :     if (state.dataExternalInterface->haveExternalInterfaceFMUImport) {
     124      143523 :         std::string errorMessage; // Error message
     125      143523 :         errorMessage.reserve(100);
     126      143523 :         char *errorMessagePtr(errorMessage.data());
     127      143523 :         const int retValErrMsg = checkOperatingSystem(errorMessagePtr);
     128      143523 :         if (retValErrMsg != 0) {
     129           0 :             ShowSevereError(state, format("ExternalInterface/ExternalInterfaceExchangeVariables:{}", errorMessagePtr));
     130           0 :             state.dataExternalInterface->ErrorsFound = true;
     131           0 :             StopExternalInterfaceIfError(state);
     132             :         }
     133             :         // initialize the FunctionalMockupUnitImport interface
     134      143523 :         InitExternalInterfaceFMUImport(state);
     135             :         // No Data exchange during design days
     136             :         // Data Exchange data during warmup and after warmup
     137      143523 :         CalcExternalInterfaceFMUImport(state);
     138      143523 :     }
     139     1946046 : }
     140             : 
     141         795 : void GetExternalInterfaceInput(EnergyPlusData &state)
     142             : {
     143             : 
     144             :     // SUBROUTINE INFORMATION:
     145             :     //       AUTHOR         Michael Wetter
     146             :     //       DATE WRITTEN   2Dec2007
     147             : 
     148             :     // PURPOSE OF THIS SUBROUTINE:
     149             :     // Obtains input data for ExternalInterface
     150             : 
     151             :     // METHODOLOGY EMPLOYED:
     152             :     // Uses InputProcessor "Get" routines to obtain data.
     153             : 
     154             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     155             :     int NumAlphas;  // Number of Alphas for each GetObjectItem call
     156             :     int NumNumbers; // Number of Numbers for each GetObjectItem call
     157             :     int IOStatus;   // Used in GetObjectItem
     158         795 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     159         795 :     cCurrentModuleObject = "ExternalInterface";
     160         795 :     state.dataExternalInterface->NumExternalInterfaces = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     161             : 
     162         798 :     for (int Loop = 1; Loop <= state.dataExternalInterface->NumExternalInterfaces;
     163             :          ++Loop) { // This loop determines whether the external interface is for FMU or BCVTB
     164           9 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     165             :                                                                  cCurrentModuleObject,
     166             :                                                                  Loop,
     167           3 :                                                                  state.dataIPShortCut->cAlphaArgs,
     168             :                                                                  NumAlphas,
     169           3 :                                                                  state.dataIPShortCut->rNumericArgs,
     170             :                                                                  NumNumbers,
     171             :                                                                  IOStatus,
     172             :                                                                  _,
     173             :                                                                  _,
     174           3 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     175           3 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     176           3 :         if (Util::SameString(state.dataIPShortCut->cAlphaArgs(1), "PtolemyServer")) { // The BCVTB interface is activated.
     177           0 :             ++state.dataExternalInterface->NumExternalInterfacesBCVTB;
     178           3 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(1),
     179             :                                     "FunctionalMockupUnitImport")) { // The functional mock up unit import interface is activated.
     180           3 :             ++state.dataExternalInterface->NumExternalInterfacesFMUImport;
     181           0 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(1),
     182             :                                     "FunctionalMockupUnitExport")) { // The functional mock up unit export interface is activated.
     183           0 :             ++state.dataExternalInterface->NumExternalInterfacesFMUExport;
     184             :         }
     185             :     }
     186             : 
     187             :     // Check if objects are used although BCVTB interface object is not defined
     188         795 :     if (state.dataExternalInterface->NumExternalInterfacesBCVTB == 0) {
     189         795 :         WarnIfExternalInterfaceObjectsAreUsed(state, "ExternalInterface:Schedule");
     190         795 :         WarnIfExternalInterfaceObjectsAreUsed(state, "ExternalInterface:Variable");
     191         795 :         WarnIfExternalInterfaceObjectsAreUsed(state, "ExternalInterface:Actuator");
     192             :     }
     193             : 
     194             :     // Check if objects are used although FMUExport interface is not defined
     195         795 :     if (state.dataExternalInterface->NumExternalInterfacesFMUExport == 0) {
     196         795 :         WarnIfExternalInterfaceObjectsAreUsed(state, "ExternalInterface:FunctionalMockupUnitExport:To:Schedule");
     197         795 :         WarnIfExternalInterfaceObjectsAreUsed(state, "ExternalInterface:FunctionalMockupUnitExport:To:Variable");
     198         795 :         WarnIfExternalInterfaceObjectsAreUsed(state, "ExternalInterface:FunctionalMockupUnitExport:To:Actuator");
     199             :     }
     200             : 
     201             :     // Check if objects are used although FMU Import interface is not defined
     202         795 :     if (state.dataExternalInterface->NumExternalInterfacesFMUImport == 0) {
     203         792 :         WarnIfExternalInterfaceObjectsAreUsed(state, "ExternalInterface:FunctionalMockupUnitImport:To:Schedule");
     204         792 :         WarnIfExternalInterfaceObjectsAreUsed(state, "ExternalInterface:FunctionalMockupUnitImport:To:Variable");
     205         792 :         WarnIfExternalInterfaceObjectsAreUsed(state, "ExternalInterface:FunctionalMockupUnitImport:To:Actuator");
     206             :     }
     207             : 
     208         795 :     if ((state.dataExternalInterface->NumExternalInterfacesBCVTB == 1) && (state.dataExternalInterface->NumExternalInterfacesFMUExport == 0)) {
     209           0 :         state.dataExternalInterface->haveExternalInterfaceBCVTB = true;
     210           0 :         DisplayString(state, "Instantiating Building Controls Virtual Test Bed");
     211           0 :         state.dataExternalInterface->varKeys.allocate(maxVar);         // Keys of report variables used for data exchange
     212           0 :         state.dataExternalInterface->varNames.allocate(maxVar);        // Names of report variables used for data exchange
     213           0 :         state.dataExternalInterface->inpVarTypes.dimension(maxVar, 0); // Names of report variables used for data exchange
     214           0 :         state.dataExternalInterface->inpVarNames.allocate(maxVar);     // Names of report variables used for data exchange
     215           0 :         VerifyExternalInterfaceObject(state);
     216         795 :     } else if ((state.dataExternalInterface->NumExternalInterfacesBCVTB == 0) && (state.dataExternalInterface->NumExternalInterfacesFMUExport == 1)) {
     217           0 :         state.dataExternalInterface->haveExternalInterfaceFMUExport = true;
     218           0 :         state.dataExternalInterface->FMUExportActivate = 1;
     219           0 :         DisplayString(state, "Instantiating FunctionalMockupUnitExport interface");
     220           0 :         state.dataExternalInterface->varKeys.allocate(maxVar);         // Keys of report variables used for data exchange
     221           0 :         state.dataExternalInterface->varNames.allocate(maxVar);        // Names of report variables used for data exchange
     222           0 :         state.dataExternalInterface->inpVarTypes.dimension(maxVar, 0); // Names of report variables used for data exchange
     223           0 :         state.dataExternalInterface->inpVarNames.allocate(maxVar);     // Names of report variables used for data exchange
     224           0 :         VerifyExternalInterfaceObject(state);
     225         795 :     } else if ((state.dataExternalInterface->NumExternalInterfacesBCVTB == 1) && (state.dataExternalInterface->NumExternalInterfacesFMUExport != 0)) {
     226           0 :         ShowSevereError(state, "GetExternalInterfaceInput: Cannot have Ptolemy and FMU-Export interface simultaneously.");
     227           0 :         state.dataExternalInterface->ErrorsFound = true;
     228             :     }
     229             : 
     230         795 :     if ((state.dataExternalInterface->NumExternalInterfacesFMUImport == 1) && (state.dataExternalInterface->NumExternalInterfacesFMUExport == 0)) {
     231           3 :         state.dataExternalInterface->haveExternalInterfaceFMUImport = true;
     232           3 :         DisplayString(state, "Instantiating FunctionalMockupUnitImport interface");
     233           3 :         cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport";
     234           3 :         state.dataExternalInterface->NumFMUObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     235           3 :         VerifyExternalInterfaceObject(state);
     236         792 :     } else if ((state.dataExternalInterface->NumExternalInterfacesFMUImport == 1) &&
     237           0 :                (state.dataExternalInterface->NumExternalInterfacesFMUExport != 0)) {
     238           0 :         ShowSevereError(state, "GetExternalInterfaceInput: Cannot have FMU-Import and FMU-Export interface simultaneously.");
     239           0 :         state.dataExternalInterface->ErrorsFound = true;
     240             :     }
     241             : 
     242         795 :     if (state.dataExternalInterface->NumExternalInterfacesBCVTB > 1) {
     243           0 :         ShowSevereError(state, "GetExternalInterfaceInput: Cannot have more than one Ptolemy interface.");
     244           0 :         ShowContinueError(state, "GetExternalInterfaceInput: Errors found in input.");
     245           0 :         state.dataExternalInterface->ErrorsFound = true;
     246             :     }
     247             : 
     248         795 :     if (state.dataExternalInterface->NumExternalInterfacesFMUExport > 1) {
     249           0 :         ShowSevereError(state, "GetExternalInterfaceInput: Cannot have more than one FMU-Export interface.");
     250           0 :         ShowContinueError(state, "Errors found in input.");
     251           0 :         state.dataExternalInterface->ErrorsFound = true;
     252             :     }
     253             : 
     254         795 :     if (state.dataExternalInterface->NumExternalInterfacesFMUImport > 1) {
     255           0 :         ShowSevereError(state, "GetExternalInterfaceInput: Cannot have more than one FMU-Import interface.");
     256           0 :         ShowContinueError(state, "Errors found in input.");
     257           0 :         state.dataExternalInterface->ErrorsFound = true;
     258             :     }
     259             : 
     260         795 :     if (state.dataExternalInterface->ErrorsFound) {
     261           0 :         ShowFatalError(state, "GetExternalInterfaceInput: preceding conditions cause termination.");
     262             :     }
     263             : 
     264         795 :     StopExternalInterfaceIfError(state);
     265         795 : }
     266             : 
     267         824 : void StopExternalInterfaceIfError(EnergyPlusData &state)
     268             : {
     269             :     // SUBROUTINE INFORMATION:
     270             :     //       AUTHOR         Michael Wetter
     271             :     //       DATE WRITTEN   9Jan2008
     272             : 
     273             :     // PURPOSE OF THIS SUBROUTINE:
     274             :     // This subroutine gracefully stops the ExternalInterface if an error has been found.
     275             :     // It sends an appropriate message to the ExternalInterface
     276             :     // and then calls a fatal error to stop EnergyPlus.
     277             : 
     278             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     279         824 :     int constexpr flag1(-10);
     280         824 :     int constexpr flag2(-20);
     281             : 
     282         824 :     if ((state.dataExternalInterface->NumExternalInterfacesBCVTB != 0) || (state.dataExternalInterface->NumExternalInterfacesFMUExport != 0)) {
     283           0 :         if (state.dataExternalInterface->ErrorsFound) {
     284             :             // Check if the socket is open
     285           0 :             if (state.dataExternalInterface->socketFD >= 0) {
     286             :                 int retVal; // Return value, needed to catch return value of function call
     287             :                 // Socket is open
     288           0 :                 if (state.dataExternalInterface->simulationStatus == 1) {
     289           0 :                     retVal = sendclientmessage(&state.dataExternalInterface->socketFD, &flag1);
     290             :                 } else {
     291           0 :                     retVal = sendclientmessage(&state.dataExternalInterface->socketFD, &flag2);
     292             :                 }
     293           0 :                 if (retVal == 0) {
     294           0 :                     ShowSevereError(state, "External Interface not found.");
     295             :                 }
     296             :             }
     297           0 :             ShowFatalError(state, "Error in ExternalInterface: Check EnergyPlus *.err file.");
     298             :         }
     299             :     }
     300         824 :     if (state.dataExternalInterface->NumExternalInterfacesFMUImport != 0) {
     301          32 :         if (state.dataExternalInterface->ErrorsFound) {
     302           0 :             ShowFatalError(state, "ExternalInterface/StopExternalInterfaceIfError: Error in ExternalInterface: Check EnergyPlus *.err file.");
     303             :         }
     304             :     }
     305         824 : }
     306             : 
     307           0 : void CloseSocket(EnergyPlusData &state, int const FlagToWriteToSocket)
     308             : {
     309             :     // SUBROUTINE INFORMATION:
     310             :     //       AUTHOR         Michael Wetter
     311             :     //       DATE WRITTEN   December 2008
     312             : 
     313             :     // PURPOSE OF THIS SUBROUTINE:
     314             :     // This subroutine tries to write the optional error code to the
     315             :     // socket and then closes the socket
     316             : 
     317             :     // SUBROUTINE ARGUMENT DEFINITIONS:
     318             :     // +1: E+ reached final time
     319             :     // -1: E+ had some error
     320             : 
     321             :     // Try to establish socket connection. This is needed if Ptolemy started E+,
     322             :     //  but E+ had an error before the call to InitExternalInterface.
     323             : 
     324           0 :     bool fileExist = FileSystem::fileExists(state.dataExternalInterface->socCfgFilPath);
     325             : 
     326           0 :     if ((state.dataExternalInterface->socketFD == -1) && fileExist) {
     327           0 :         state.dataExternalInterface->socketFD = establishclientsocket(FileSystem::toString(state.dataExternalInterface->socCfgFilPath).c_str());
     328             :     }
     329             : 
     330           0 :     if (state.dataExternalInterface->socketFD >= 0) {
     331             :         // TODO: use return value from this function?
     332           0 :         sendclientmessage(&state.dataExternalInterface->socketFD, &FlagToWriteToSocket);
     333             :         // Don't close socket as this may give sometimes an IOException in Windows
     334             :         // This problem seems to affect only Windows but not Mac
     335             :         //     close(state.dataExternalInterface->socketFD)
     336             :     }
     337           0 : }
     338             : 
     339           0 : void ParseString(std::string const &str, // The string, with all elements separated by ';'
     340             :                  Array1D_string &ele,    // The elements
     341             :                  int const nEle          // The number of elements
     342             : )
     343             : {
     344             :     // SUBROUTINE INFORMATION:
     345             :     //       AUTHOR         Michael Wetter
     346             :     //       DATE WRITTEN   8Jan2008
     347             : 
     348             :     // PURPOSE OF THIS SUBROUTINE:
     349             :     // This subroutine parses the semicolon separated string xmlStr
     350             :     // and assigns each element to ele
     351             : 
     352             :     // SUBROUTINE VARIABLE DEFINITIONS:
     353             :     std::string::size_type iSta; // Start of substring
     354             :     std::string::size_type iCol; // Index of ;
     355             : 
     356           0 :     std::string::size_type lenStr = len(str);
     357           0 :     std::string::size_type iEnd = 0;
     358           0 :     for (int i = 1; i <= nEle; ++i) {
     359           0 :         iSta = iEnd; // add one to skip ';'
     360           0 :         iCol = str.find(';', iSta);
     361           0 :         if (iCol != std::string::npos) {
     362           0 :             iEnd = iCol + 1;
     363             :         } else { // Use rest of string
     364           0 :             iEnd = lenStr;
     365             :         }
     366           0 :         ele(i) = Util::makeUPPER(str.substr(iSta, iEnd - iSta - 1));
     367             :     }
     368           0 : }
     369             : 
     370           0 : void InitExternalInterface(EnergyPlusData &state)
     371             : {
     372             :     // SUBROUTINE INFORMATION:
     373             :     //       AUTHOR         Michael Wetter
     374             :     //       DATE WRITTEN   2Dec2007
     375             :     //       MODIFIED       Rui Zhang Aug 2009
     376             : 
     377             :     // PURPOSE OF THIS SUBROUTINE:
     378             :     // This subroutine is for initializations of the ExternalInterface
     379             : 
     380             :     // SUBROUTINE PARAMETER DEFINITIONS:
     381             : 
     382           0 :     std::string const simCfgFilNam("variables.cfg");               // Configuration file
     383           0 :     std::string const xmlStrInKey("schedule,variable,actuator\0"); // xml values in string, separated by ','
     384             : 
     385           0 :     if (state.dataExternalInterface->InitExternalInterfacefirstCall) {
     386           0 :         DisplayString(state, "ExternalInterface initializes.");
     387             :         // do one time initializations
     388             : 
     389           0 :         if (state.dataExternalInterface->haveExternalInterfaceBCVTB) {
     390             :             // Check version number
     391           0 :             int mainVersion = getmainversionnumber();
     392           0 :             if (mainVersion < 0) {
     393           0 :                 ShowSevereError(state, "ExternalInterface: BCVTB is not installed in this version.");
     394           0 :                 state.dataExternalInterface->ErrorsFound = true;
     395           0 :                 StopExternalInterfaceIfError(state);
     396             :             }
     397             :         }
     398             : 
     399             :         // Get port number
     400           0 :         if (FileSystem::fileExists(state.dataExternalInterface->socCfgFilPath)) {
     401           0 :             state.dataExternalInterface->socketFD = establishclientsocket(FileSystem::toString(state.dataExternalInterface->socCfgFilPath).c_str());
     402           0 :             if (state.dataExternalInterface->socketFD < 0) {
     403           0 :                 ShowSevereError(state,
     404           0 :                                 format("ExternalInterface: Could not open socket. File descriptor = {}.", state.dataExternalInterface->socketFD));
     405           0 :                 state.dataExternalInterface->ErrorsFound = true;
     406             :             }
     407             :         } else {
     408           0 :             ShowSevereError(state, format("ExternalInterface: Did not find file \"{}\".", state.dataExternalInterface->socCfgFilPath));
     409           0 :             ShowContinueError(state, "This file needs to be in same directory as in.idf.");
     410           0 :             ShowContinueError(state, "Check the documentation for the ExternalInterface.");
     411           0 :             state.dataExternalInterface->ErrorsFound = true;
     412             :         }
     413             : 
     414             :         // Make sure that idf file specified a run period other than
     415             :         // design day and system sizing.
     416           0 :         ValidateRunControl(state);
     417             : 
     418           0 :         StopExternalInterfaceIfError(state);
     419             : 
     420             :         // make a single length here for all strings to be passed to getepvariables
     421           0 :         size_t lenXmlStr(maxVar * Constant::MaxNameLength); // Length of strings being passed to getepvariables
     422             : 
     423             :         // initialize all the strings to this length with blanks
     424           0 :         std::string xmlStrOut = std::string(lenXmlStr, ' ');
     425           0 :         std::string xmlStrOutTyp = std::string(lenXmlStr, ' ');
     426           0 :         std::string xmlStrIn = std::string(lenXmlStr, ' ');
     427             : 
     428             :         // Get input and output variables for EnergyPlus in sequence
     429             :         // Check if simCfgFilNam exists.
     430           0 :         if (FileSystem::fileExists(simCfgFilNam)) {
     431             :             int retVal; // Return value of function call, used for error handling
     432             : 
     433             :             // preprocess the strings into char vectors before making the library call
     434           0 :             std::vector<char> xmlStrOutTypArr(getCharArrayFromString(xmlStrOutTyp));
     435           0 :             std::vector<char> xmlStrOutArr(getCharArrayFromString(xmlStrOut));
     436           0 :             std::vector<char> xmlStrInArr(getCharArrayFromString(xmlStrIn));
     437             : 
     438             :             // now make the library call
     439           0 :             if (state.dataExternalInterface->haveExternalInterfaceBCVTB) {
     440           0 :                 retVal = getepvariables(simCfgFilNam.c_str(),
     441           0 :                                         &xmlStrOutTypArr[0],
     442           0 :                                         &xmlStrOutArr[0],
     443           0 :                                         &state.dataExternalInterface->nOutVal,
     444             :                                         xmlStrInKey.c_str(),
     445           0 :                                         &state.dataExternalInterface->nInKeys,
     446           0 :                                         &xmlStrInArr[0],
     447           0 :                                         &state.dataExternalInterface->nInpVar,
     448           0 :                                         state.dataExternalInterface->inpVarTypes.data(),
     449             :                                         &lenXmlStr);
     450           0 :             } else if (state.dataExternalInterface->haveExternalInterfaceFMUExport) {
     451           0 :                 retVal = getepvariablesFMU(simCfgFilNam.c_str(),
     452           0 :                                            &xmlStrOutTypArr[0],
     453           0 :                                            &xmlStrOutArr[0],
     454           0 :                                            &state.dataExternalInterface->nOutVal,
     455             :                                            xmlStrInKey.c_str(),
     456           0 :                                            &state.dataExternalInterface->nInKeys,
     457           0 :                                            &xmlStrInArr[0],
     458           0 :                                            &state.dataExternalInterface->nInpVar,
     459           0 :                                            state.dataExternalInterface->inpVarTypes.data(),
     460             :                                            &lenXmlStr);
     461             :             } else {
     462             :                 // there should be no else condition at this point, however we'll still assign the error value for completeness
     463           0 :                 retVal = -1;
     464             :             }
     465             : 
     466             :             // then postprocess the char vectors in case they are used after the fact
     467           0 :             xmlStrOutTyp = getStringFromCharArray(xmlStrOutTypArr);
     468           0 :             xmlStrOut = getStringFromCharArray(xmlStrOutArr);
     469           0 :             xmlStrIn = getStringFromCharArray(xmlStrInArr);
     470             : 
     471           0 :             xmlStrOutTypArr.clear();
     472           0 :             xmlStrOutArr.clear();
     473           0 :             xmlStrInArr.clear();
     474             : 
     475             :             // handle errors when reading variables.cfg file
     476           0 :             if (retVal < 0) {
     477           0 :                 ShowSevereError(state, "ExternalInterface: Error when getting input and output variables for EnergyPlus,");
     478           0 :                 ShowContinueError(state, "check simulation.log for error message.");
     479           0 :                 state.dataExternalInterface->ErrorsFound = true;
     480             :             }
     481             : 
     482           0 :         } else {
     483             : 
     484           0 :             ShowSevereError(state, format("ExternalInterface: Did not find file \"{}\".", simCfgFilNam));
     485           0 :             ShowContinueError(state, "This file needs to be in same directory as in.idf.");
     486           0 :             ShowContinueError(state, "Check the documentation for the ExternalInterface.");
     487           0 :             state.dataExternalInterface->ErrorsFound = true;
     488             :         }
     489           0 :         StopExternalInterfaceIfError(state);
     490             : 
     491           0 :         if (state.dataExternalInterface->nOutVal + state.dataExternalInterface->nInpVar > maxVar) {
     492           0 :             ShowSevereError(state, "ExternalInterface: Too many variables to be exchanged.");
     493           0 :             ShowContinueError(state, format("Attempted to exchange {} outputs", state.dataExternalInterface->nOutVal));
     494           0 :             ShowContinueError(state, format("plus {} inputs.", state.dataExternalInterface->nOutVal));
     495           0 :             ShowContinueError(state, format("Maximum allowed is sum is {}.", maxVar));
     496           0 :             ShowContinueError(state, "To fix, increase maxVar in ExternalInterface.cc");
     497           0 :             state.dataExternalInterface->ErrorsFound = true;
     498             :         }
     499           0 :         StopExternalInterfaceIfError(state);
     500             : 
     501           0 :         if (state.dataExternalInterface->nOutVal < 0) {
     502           0 :             ShowSevereError(state, "ExternalInterface: Error when getting number of xml values for outputs.");
     503           0 :             state.dataExternalInterface->ErrorsFound = true;
     504             :         } else {
     505           0 :             ParseString(xmlStrOut, state.dataExternalInterface->varNames, state.dataExternalInterface->nOutVal);
     506           0 :             ParseString(xmlStrOutTyp, state.dataExternalInterface->varKeys, state.dataExternalInterface->nOutVal);
     507             :         }
     508           0 :         StopExternalInterfaceIfError(state);
     509             : 
     510           0 :         if (state.dataExternalInterface->nInpVar < 0) {
     511           0 :             ShowSevereError(state, "ExternalInterface: Error when getting number of xml values for inputs.");
     512           0 :             state.dataExternalInterface->ErrorsFound = true;
     513             :         } else {
     514           0 :             ParseString(xmlStrIn, state.dataExternalInterface->inpVarNames, state.dataExternalInterface->nInpVar);
     515             :         }
     516           0 :         StopExternalInterfaceIfError(state);
     517             : 
     518           0 :         DisplayString(state, format("Number of outputs in ExternalInterface = {}", state.dataExternalInterface->nOutVal));
     519           0 :         DisplayString(state, format("Number of inputs  in ExternalInterface = {}", state.dataExternalInterface->nInpVar));
     520             : 
     521           0 :         state.dataExternalInterface->InitExternalInterfacefirstCall = false;
     522             : 
     523           0 :     } else if (!state.dataExternalInterface->configuredControlPoints) {
     524           0 :         state.dataExternalInterface->keyVarIndexes.allocate(state.dataExternalInterface->nOutVal);
     525           0 :         state.dataExternalInterface->varTypes.allocate(state.dataExternalInterface->nOutVal);
     526           0 :         GetReportVariableKey(state,
     527           0 :                              state.dataExternalInterface->varKeys,
     528           0 :                              state.dataExternalInterface->nOutVal,
     529           0 :                              state.dataExternalInterface->varNames,
     530           0 :                              state.dataExternalInterface->keyVarIndexes,
     531           0 :                              state.dataExternalInterface->varTypes);
     532           0 :         state.dataExternalInterface->varInd.allocate(state.dataExternalInterface->nInpVar);
     533           0 :         for (int i = 1; i <= state.dataExternalInterface->nInpVar; ++i) {
     534           0 :             if (state.dataExternalInterface->inpVarTypes(i) == indexSchedule) {
     535           0 :                 state.dataExternalInterface->varInd(i) = ScheduleManager::GetDayScheduleIndex(state, state.dataExternalInterface->inpVarNames(i));
     536           0 :             } else if (state.dataExternalInterface->inpVarTypes(i) == indexVariable) {
     537           0 :                 state.dataExternalInterface->varInd(i) =
     538           0 :                     RuntimeLanguageProcessor::FindEMSVariable(state, state.dataExternalInterface->inpVarNames(i), 0);
     539           0 :             } else if (state.dataExternalInterface->inpVarTypes(i) == indexActuator) {
     540           0 :                 state.dataExternalInterface->varInd(i) =
     541           0 :                     RuntimeLanguageProcessor::FindEMSVariable(state, state.dataExternalInterface->inpVarNames(i), 0);
     542             :             }
     543           0 :             if (state.dataExternalInterface->varInd(i) <= 0) {
     544           0 :                 ShowSevereError(state,
     545           0 :                                 format("ExternalInterface: Error, xml file \"{}\" declares variable \"{}\",",
     546             :                                        simCfgFilNam,
     547           0 :                                        state.dataExternalInterface->inpVarNames(i)));
     548           0 :                 ShowContinueError(state, "but variable was not found in idf file.");
     549           0 :                 state.dataExternalInterface->ErrorsFound = true;
     550             :             }
     551             :         }
     552           0 :         StopExternalInterfaceIfError(state);
     553             :         // Configure Erl variables
     554           0 :         for (int i = 1; i <= state.dataExternalInterface->nInpVar; ++i) {
     555           0 :             if (state.dataExternalInterface->inpVarTypes(i) == indexVariable) { // ems-globalvariable
     556           0 :                 state.dataExternalInterface->useEMS = true;
     557           0 :                 if (!RuntimeLanguageProcessor::isExternalInterfaceErlVariable(state, state.dataExternalInterface->varInd(i))) {
     558           0 :                     ShowSevereError(state,
     559           0 :                                     format("ExternalInterface: Error, xml file \"{}\" declares variable \"{}\",",
     560             :                                            simCfgFilNam,
     561           0 :                                            state.dataExternalInterface->inpVarNames(i)));
     562           0 :                     ShowContinueError(state, "But this variable is an ordinary Erl variable, not an ExternalInterface variable.");
     563           0 :                     ShowContinueError(state, "You must specify a variable of type \"ExternalInterface:Variable\".");
     564           0 :                     state.dataExternalInterface->ErrorsFound = true;
     565             :                 }
     566           0 :             } else if (state.dataExternalInterface->inpVarTypes(i) == indexActuator) { // ems-actuator
     567           0 :                 state.dataExternalInterface->useEMS = true;
     568           0 :                 if (!RuntimeLanguageProcessor::isExternalInterfaceErlVariable(state, state.dataExternalInterface->varInd(i))) {
     569           0 :                     ShowSevereError(state,
     570           0 :                                     format("ExternalInterface: Error, xml file \"{}\" declares variable \"{}\",",
     571             :                                            simCfgFilNam,
     572           0 :                                            state.dataExternalInterface->inpVarNames(i)));
     573           0 :                     ShowContinueError(state, "But this variable is an ordinary Erl actuator, not an ExternalInterface actuator.");
     574           0 :                     ShowContinueError(state, "You must specify a variable of type \"ExternalInterface:Actuator\".");
     575           0 :                     state.dataExternalInterface->ErrorsFound = true;
     576             :                 }
     577             :             }
     578             :         }
     579           0 :         state.dataExternalInterface->configuredControlPoints = true;
     580             :     }
     581           0 :     StopExternalInterfaceIfError(state);
     582           0 : }
     583             : 
     584      143520 : void GetSetVariablesAndDoStepFMUImport(EnergyPlusData &state)
     585             : {
     586             :     // SUBROUTINE INFORMATION:
     587             :     //       AUTHOR         Thierry S. Nouidui, Michael Wetter, Wangda Zuo
     588             :     //       DATE WRITTEN   08Aug2011
     589             : 
     590             :     // PURPOSE OF THIS SUBROUTINE:
     591             :     // This routine gets, sets and does the time integration in FMUs.
     592             : 
     593      287040 :     for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
     594      287040 :         for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
     595      143520 :             if (state.dataExternalInterface->FlagReIni) {
     596             :                 // Get from FMUs, values that will be set in EnergyPlus (Schedule)
     597          63 :                 for (int k = 1; k <= state.dataExternalInterface->FMUTemp(i).Instance(j).NumOutputVariablesSchedule; ++k) {
     598          34 :                     state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).RealVarValue =
     599          34 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableSchedule(k).RealVarValue;
     600             :                 }
     601             : 
     602             :                 // Get from FMUs, values that will be set in EnergyPlus (Variable)
     603          35 :                 for (int k = 1; k <= state.dataExternalInterface->FMUTemp(i).Instance(j).NumOutputVariablesVariable; ++k) {
     604           6 :                     state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).RealVarValue =
     605           6 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableVariable(k).RealVarValue;
     606             :                 }
     607             : 
     608             :                 // Get from FMUs, values that will be set in EnergyPlus (Actuator)
     609          35 :                 for (int k = 1; k <= state.dataExternalInterface->FMUTemp(i).Instance(j).NumOutputVariablesActuator; ++k) {
     610           6 :                     state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).RealVarValue =
     611           6 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableActuator(k).RealVarValue;
     612             :                 }
     613             :             } else {
     614             :                 // Get from FMUs, values that will be set in EnergyPlus (Schedule)
     615             : 
     616      143491 :                 if (size(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule) > 0) {
     617             : 
     618             :                     // generate vectors here first
     619       36655 :                     std::vector<unsigned int> valueReferenceVec;
     620       36655 :                     std::vector<Real64> realVarValueVec;
     621      109965 :                     for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule); ++x) {
     622       73310 :                         valueReferenceVec.push_back(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(x).ValueReference);
     623       73310 :                         realVarValueVec.push_back(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(x).RealVarValue);
     624             :                     }
     625             : 
     626             :                     // pass in the vectors as pointers to the first member of the vector
     627       36655 :                     state.dataExternalInterface->FMU(i).Instance(j).fmistatus =
     628       36655 :                         fmiEPlusGetReal(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
     629       36655 :                                         &valueReferenceVec[0],
     630       36655 :                                         &realVarValueVec[0],
     631       36655 :                                         &state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesSchedule,
     632       36655 :                                         &state.dataExternalInterface->FMU(i).Instance(j).Index);
     633             : 
     634      109965 :                     for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule); ++x) {
     635       73310 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(x).ValueReference = valueReferenceVec[x - 1];
     636       73310 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(x).RealVarValue = realVarValueVec[x - 1];
     637             :                     }
     638             : 
     639       36655 :                     if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiOK) {
     640           0 :                         ShowSevereError(state, "ExternalInterface/GetSetVariablesAndDoStepFMUImport: Error when trying to get outputs");
     641           0 :                         ShowContinueError(state,
     642           0 :                                           format("in instance \"{}\" of FMU \"{}\"",
     643           0 :                                                  state.dataExternalInterface->FMU(i).Instance(j).Name,
     644           0 :                                                  state.dataExternalInterface->FMU(i).Name));
     645           0 :                         ShowContinueError(state, format("Error Code = \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).fmistatus));
     646           0 :                         state.dataExternalInterface->ErrorsFound = true;
     647           0 :                         StopExternalInterfaceIfError(state);
     648             :                     }
     649       36655 :                 }
     650             : 
     651             :                 // generate vectors here first
     652      143491 :                 if (size(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable) > 0) {
     653             : 
     654       53418 :                     std::vector<unsigned int> valueReferenceVec2;
     655       53418 :                     std::vector<Real64> realVarValueVec2;
     656      106836 :                     for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable); ++x) {
     657       53418 :                         valueReferenceVec2.push_back(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(x).ValueReference);
     658       53418 :                         realVarValueVec2.push_back(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(x).RealVarValue);
     659             :                     }
     660             : 
     661             :                     // pass in the vectors as pointers to the first member of the vector
     662       53418 :                     state.dataExternalInterface->FMU(i).Instance(j).fmistatus =
     663       53418 :                         fmiEPlusGetReal(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
     664       53418 :                                         &valueReferenceVec2[0],
     665       53418 :                                         &realVarValueVec2[0],
     666       53418 :                                         &state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesVariable,
     667       53418 :                                         &state.dataExternalInterface->FMU(i).Instance(j).Index);
     668             : 
     669      106836 :                     for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable); ++x) {
     670       53418 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(x).ValueReference = valueReferenceVec2[x - 1];
     671       53418 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(x).RealVarValue = realVarValueVec2[x - 1];
     672             :                     }
     673             : 
     674       53418 :                     if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiOK) {
     675           0 :                         ShowSevereError(state, "ExternalInterface/GetSetVariablesAndDoStepFMUImport: Error when trying to get outputs");
     676           0 :                         ShowContinueError(state,
     677           0 :                                           format("in instance \"{}\" of FMU \"{}\"",
     678           0 :                                                  state.dataExternalInterface->FMU(i).Instance(j).Name,
     679           0 :                                                  state.dataExternalInterface->FMU(i).Name));
     680           0 :                         ShowContinueError(state, format("Error Code = \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).fmistatus));
     681           0 :                         state.dataExternalInterface->ErrorsFound = true;
     682           0 :                         StopExternalInterfaceIfError(state);
     683             :                     }
     684       53418 :                 }
     685             : 
     686      143491 :                 if (size(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator) > 0) {
     687             : 
     688             :                     // generate vectors here first
     689       53418 :                     std::vector<unsigned int> valueReferenceVec3;
     690       53418 :                     std::vector<Real64> realVarValueVec3;
     691      106836 :                     for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator); ++x) {
     692       53418 :                         valueReferenceVec3.push_back(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(x).ValueReference);
     693       53418 :                         realVarValueVec3.push_back(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(x).RealVarValue);
     694             :                     }
     695             : 
     696             :                     // pass in the vectors as pointers to the first member of the vector
     697       53418 :                     state.dataExternalInterface->FMU(i).Instance(j).fmistatus =
     698       53418 :                         fmiEPlusGetReal(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
     699       53418 :                                         &valueReferenceVec3[0],
     700       53418 :                                         &realVarValueVec3[0],
     701       53418 :                                         &state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesActuator,
     702       53418 :                                         &state.dataExternalInterface->FMU(i).Instance(j).Index);
     703             : 
     704      106836 :                     for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator); ++x) {
     705       53418 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(x).ValueReference = valueReferenceVec3[x - 1];
     706       53418 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(x).RealVarValue = realVarValueVec3[x - 1];
     707             :                     }
     708             : 
     709       53418 :                     if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiOK) {
     710           0 :                         ShowSevereError(state, "ExternalInterface/GetSetVariablesAndDoStepFMUImport: Error when trying to get outputs");
     711           0 :                         ShowContinueError(state,
     712           0 :                                           format("in instance \"{}\" of FMU \"{}\"",
     713           0 :                                                  state.dataExternalInterface->FMU(i).Instance(j).Name,
     714           0 :                                                  state.dataExternalInterface->FMU(i).Name));
     715           0 :                         ShowContinueError(state, format("Error Code = \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).fmistatus));
     716           0 :                         state.dataExternalInterface->ErrorsFound = true;
     717           0 :                         StopExternalInterfaceIfError(state);
     718             :                     }
     719       53418 :                 }
     720             :             }
     721             : 
     722             :             // Set in EnergyPlus the values of the schedules
     723      216864 :             for (int k = 1; k <= state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesSchedule; ++k) {
     724       73344 :                 ScheduleManager::ExternalInterfaceSetSchedule(
     725             :                     state,
     726       73344 :                     state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableSchedule(k).VarIndex,
     727       73344 :                     state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).RealVarValue);
     728             :             }
     729             : 
     730             :             // Set in EnergyPlus the values of the variables
     731      196944 :             for (int k = 1; k <= state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesVariable; ++k) {
     732      106848 :                 RuntimeLanguageProcessor::ExternalInterfaceSetErlVariable(
     733             :                     state,
     734       53424 :                     state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableVariable(k).VarIndex,
     735       53424 :                     state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).RealVarValue);
     736             :             }
     737             : 
     738             :             // Set in EnergyPlus the values of the actuators
     739      196944 :             for (int k = 1; k <= state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesActuator; ++k) {
     740      106848 :                 RuntimeLanguageProcessor::ExternalInterfaceSetErlVariable(
     741             :                     state,
     742       53424 :                     state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableActuator(k).VarIndex,
     743       53424 :                     state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).RealVarValue);
     744             :             }
     745             : 
     746      143520 :             if (state.dataExternalInterface->FirstCallGetSetDoStep) {
     747             :                 // Get from EnergyPlus, values that will be set in fmus
     748          11 :                 for (int k = 1; k <= state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF; ++k) {
     749             :                     // This make sure that the variables are updated at the Zone Time Step
     750           8 :                     state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).RTSValue =
     751           8 :                         GetInternalVariableValue(state,
     752           8 :                                                  state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarType,
     753           8 :                                                  state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarIndex);
     754             :                 }
     755             :             } else {
     756             :                 // Get from EnergyPlus, values that will be set in fmus
     757      503893 :                 for (int k = 1; k <= state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF; ++k) {
     758             :                     // This make sure that the variables are updated at the Zone Time Step
     759      360376 :                     state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).RTSValue =
     760      360376 :                         GetInternalVariableValueExternalInterface(state,
     761      360376 :                                                                   state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarType,
     762      360376 :                                                                   state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarIndex);
     763             :                 }
     764             :             }
     765             : 
     766      143520 :             if (!state.dataExternalInterface->FlagReIni) {
     767             : 
     768             :                 // generate vectors here first
     769      143491 :                 std::vector<unsigned int> valueReferenceVec4;
     770      503783 :                 for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable); ++x) {
     771      360292 :                     valueReferenceVec4.push_back(state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(x).ValueReference);
     772             :                 }
     773             : 
     774      143491 :                 std::vector<Real64> rtsValueVec4;
     775      503783 :                 for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable); ++x) {
     776      360292 :                     rtsValueVec4.push_back(state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(x).RTSValue);
     777             :                 }
     778             : 
     779      143491 :                 state.dataExternalInterface->FMU(i).Instance(j).fmistatus =
     780      143491 :                     fmiEPlusSetReal(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
     781      143491 :                                     &valueReferenceVec4[0],
     782      143491 :                                     &rtsValueVec4[0],
     783      143491 :                                     &state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF,
     784      143491 :                                     &state.dataExternalInterface->FMU(i).Instance(j).Index);
     785             : 
     786      143491 :                 if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiOK) {
     787           0 :                     ShowSevereError(state, "ExternalInterface/GetSetVariablesAndDoStepFMUImport: Error when trying to set inputs");
     788           0 :                     ShowContinueError(state,
     789           0 :                                       format("in instance \"{}\" of FMU \"{}\"",
     790           0 :                                              state.dataExternalInterface->FMU(i).Instance(j).Name,
     791           0 :                                              state.dataExternalInterface->FMU(i).Name));
     792           0 :                     ShowContinueError(state, format("Error Code = \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).fmistatus));
     793           0 :                     state.dataExternalInterface->ErrorsFound = true;
     794           0 :                     StopExternalInterfaceIfError(state);
     795             :                 }
     796      143491 :             }
     797      143520 :             int localfmitrue(fmiTrue);
     798             :             // Call and simulate the FMUs to get values at the corresponding timestep.
     799      143520 :             state.dataExternalInterface->FMU(i).Instance(j).fmistatus = fmiEPlusDoStep(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
     800      143520 :                                                                                        &state.dataExternalInterface->tComm,
     801      143520 :                                                                                        &state.dataExternalInterface->hStep,
     802             :                                                                                        &localfmitrue,
     803      143520 :                                                                                        &state.dataExternalInterface->FMU(i).Instance(j).Index);
     804      143520 :             if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiOK) {
     805           0 :                 ShowSevereError(state, "ExternalInterface/GetSetVariablesAndDoStepFMUImport: Error when trying to");
     806           0 :                 ShowContinueError(state, format("do the coSimulation with instance \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).Name));
     807           0 :                 ShowContinueError(state, format("of FMU \"{}\"", state.dataExternalInterface->FMU(i).Name));
     808           0 :                 ShowContinueError(state, format("Error Code = \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).fmistatus));
     809           0 :                 state.dataExternalInterface->ErrorsFound = true;
     810           0 :                 StopExternalInterfaceIfError(state);
     811             :             }
     812             :         }
     813             :     }
     814             : 
     815             :     // If we have Erl variables, we need to call ManageEMS so that they get updated in the Erl data structure
     816      143520 :     if (state.dataExternalInterface->useEMS) {
     817             :         bool anyRan;
     818      106848 :         EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::ExternalInterface, anyRan, ObjexxFCL::Optional_int_const());
     819             :     }
     820             : 
     821      143520 :     state.dataExternalInterface->FirstCallGetSetDoStep = false;
     822      143520 : }
     823             : 
     824          32 : void InstantiateInitializeFMUImport(EnergyPlusData &state)
     825             : {
     826             :     // SUBROUTINE INFORMATION:
     827             :     //       AUTHOR         Thierry S. Nouidui, Michael Wetter, Wangda Zuo
     828             :     //       DATE WRITTEN   08Aug2011
     829             : 
     830             :     // PURPOSE OF THIS SUBROUTINE:
     831             :     // This routine instantiates and initializes FMUs.
     832             : 
     833             :     // Instantiate FMUs
     834          64 :     for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
     835          64 :         for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
     836          32 :             std::string const folderStr = FileSystem::toString(state.dataExternalInterface->FMU(i).Instance(j).WorkingFolder);
     837          32 :             state.dataExternalInterface->FMU(i).Instance(j).fmicomponent =
     838          32 :                 fmiEPlusInstantiateSlave((char *)folderStr.c_str(),
     839          32 :                                          &state.dataExternalInterface->FMU(i).Instance(j).LenWorkingFolder,
     840          32 :                                          &state.dataExternalInterface->FMU(i).TimeOut,
     841          32 :                                          &state.dataExternalInterface->FMU(i).Visible,
     842          32 :                                          &state.dataExternalInterface->FMU(i).Interactive,
     843          32 :                                          &state.dataExternalInterface->FMU(i).LoggingOn,
     844          32 :                                          &state.dataExternalInterface->FMU(i).Instance(j).Index);
     845             :             // TODO: This is doing a null pointer check; OK?
     846          32 :             if (!state.dataExternalInterface->FMU(i).Instance(j).fmicomponent) {
     847           0 :                 ShowSevereError(state, "ExternalInterface/CalcExternalInterfaceFMUImport: Error when trying to instantiate");
     848           0 :                 ShowContinueError(state,
     849           0 :                                   format("instance \"{}\" of FMU \"{}\"",
     850           0 :                                          state.dataExternalInterface->FMU(i).Instance(j).Name,
     851           0 :                                          state.dataExternalInterface->FMU(i).Name));
     852           0 :                 state.dataExternalInterface->ErrorsFound = true;
     853           0 :                 StopExternalInterfaceIfError(state);
     854             :             }
     855          32 :         }
     856             :     }
     857             : 
     858             :     // Initialize FMUs
     859          32 :     int localfmiTrue(fmiTrue);
     860          64 :     for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
     861          64 :         for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
     862          32 :             state.dataExternalInterface->FMU(i).Instance(j).fmistatus =
     863          32 :                 fmiEPlusInitializeSlave(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
     864          32 :                                         &state.dataExternalInterface->tStart,
     865             :                                         &localfmiTrue,
     866          32 :                                         &state.dataExternalInterface->tStop,
     867          32 :                                         &state.dataExternalInterface->FMU(i).Instance(j).Index);
     868          32 :             if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiOK) {
     869           0 :                 ShowSevereError(state, "ExternalInterface/CalcExternalInterfaceFMUImport: Error when trying to initialize");
     870           0 :                 ShowContinueError(state,
     871           0 :                                   format("instance \"{}\" of FMU \"{}\"",
     872           0 :                                          state.dataExternalInterface->FMU(i).Instance(j).Name,
     873           0 :                                          state.dataExternalInterface->FMU(i).Name));
     874           0 :                 ShowContinueError(state, format("Error Code = \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).fmistatus));
     875           0 :                 state.dataExternalInterface->ErrorsFound = true;
     876           0 :                 StopExternalInterfaceIfError(state);
     877             :             }
     878             :         }
     879             :     }
     880          32 : }
     881             : 
     882           0 : void InitializeFMU(EnergyPlusData &state)
     883             : {
     884             :     // SUBROUTINE INFORMATION:
     885             :     //       AUTHOR         Thierry S. Nouidui, Michael Wetter, Wangda Zuo
     886             :     //       DATE WRITTEN   08Aug2011
     887             : 
     888             :     // PURPOSE OF THIS SUBROUTINE:
     889             :     // This routine reinitializes FMUs.
     890             : 
     891             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     892           0 :     int localfmiTrue(fmiTrue);
     893             : 
     894             :     // Initialize FMUs
     895           0 :     for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
     896           0 :         for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
     897           0 :             state.dataExternalInterface->FMU(i).Instance(j).fmistatus =
     898           0 :                 fmiEPlusInitializeSlave(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
     899           0 :                                         &state.dataExternalInterface->tStart,
     900             :                                         &localfmiTrue,
     901           0 :                                         &state.dataExternalInterface->tStop,
     902           0 :                                         &state.dataExternalInterface->FMU(i).Instance(j).Index);
     903           0 :             if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiOK) {
     904           0 :                 ShowSevereError(state, "ExternalInterface/CalcExternalInterfaceFMUImport: Error when trying to initialize");
     905           0 :                 ShowContinueError(state,
     906           0 :                                   format("instance \"{}\" of FMU \"{}\"",
     907           0 :                                          state.dataExternalInterface->FMU(i).Instance(j).Name,
     908           0 :                                          state.dataExternalInterface->FMU(i).Name));
     909           0 :                 ShowContinueError(state, format("Error Code = \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).fmistatus));
     910           0 :                 state.dataExternalInterface->ErrorsFound = true;
     911           0 :                 StopExternalInterfaceIfError(state);
     912             :             }
     913             :         }
     914             :     }
     915           0 : }
     916             : 
     917          32 : void TerminateResetFreeFMUImport(EnergyPlusData &state, int fmiEndSimulation)
     918             : {
     919             :     // SUBROUTINE INFORMATION:
     920             :     //       AUTHOR         Thierry S. Nouidui, Michael Wetter, Wangda Zuo
     921             :     //       DATE WRITTEN   08Aug2011
     922             : 
     923             :     // PURPOSE OF THIS SUBROUTINE:
     924             :     // This routine terminates the FMUs instances
     925             : 
     926             :     //----Needs to have function that allows to terminates FMU. Was not defined in version 1.0 -- fixme
     927          64 :     for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
     928          64 :         for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
     929          32 :             if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiFatal) {
     930             :                 // Cleanup slaves
     931          32 :                 state.dataExternalInterface->FMU(i).Instance(j).fmistatus =
     932          32 :                     fmiEPlusFreeSlave(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
     933          32 :                                       &state.dataExternalInterface->FMU(i).Instance(j).Index,
     934             :                                       &fmiEndSimulation);
     935             :             }
     936             :             // check if fmiComponent has been freed
     937          32 :             if (!state.dataExternalInterface->FMU(i).Instance(j).fmicomponent) {
     938           0 :                 ShowSevereError(state, "ExternalInterface/TerminateResetFreeFMUImport: Error when trying to terminate");
     939           0 :                 ShowContinueError(state,
     940           0 :                                   format("instance \"{}\" of FMU \"{}\"",
     941           0 :                                          state.dataExternalInterface->FMU(i).Instance(j).Name,
     942           0 :                                          state.dataExternalInterface->FMU(i).Name));
     943           0 :                 state.dataExternalInterface->ErrorsFound = true;
     944           0 :                 StopExternalInterfaceIfError(state);
     945             :             }
     946             :         }
     947             :     }
     948          32 : }
     949             : 
     950      143523 : void InitExternalInterfaceFMUImport(EnergyPlusData &state)
     951             : {
     952             : 
     953             :     // SUBROUTINE INFORMATION:
     954             :     //       AUTHOR         Thierry S. Nouidui, Michael Wetter, Wangda Zuo
     955             :     //       DATE WRITTEN   08Aug2011
     956             : 
     957             :     // PURPOSE OF THIS SUBROUTINE:
     958             :     // This routine initializes the input and outputs variables used for the co-simulation with FMUs.
     959             : 
     960             :     // Locals
     961      143523 :     Array1D_int keyIndexes(1);                          // Array index for
     962      143523 :     Array1D<OutputProcessor::VariableType> varTypes(1); // Array index for
     963      143523 :     Array1D_string NamesOfKeys(1);                      // Specific key name
     964      143523 :     Array1D_string NameListInstances(5);
     965      143523 :     fs::path tempFullFilePath;
     966             : 
     967      143523 :     Array1D_string strippedFileName; // remove path from entered file name
     968      143523 :     Array1D_string fullFileName;     // entered file name/found
     969             : 
     970      143523 :     if (state.dataExternalInterface->FirstCallIni) {
     971           3 :         DisplayString(state, "Initializing FunctionalMockupUnitImport interface");
     972             :         // do one time initializations
     973           3 :         ValidateRunControl(state);
     974           3 :         state.dataExternalInterface->FMU.allocate(state.dataExternalInterface->NumFMUObjects);
     975             : 
     976             :         // there used to be code in here to apply the root working folder to create an absolute path
     977             :         // however, this wasn't working, as the root working folder was coming back empty
     978             :         // in any case, the relative paths work fine here
     979             : 
     980             :         // post process as needed in case these are used later
     981           3 :         state.dataExternalInterface->FMURootWorkingFolder = fs::path("tmp-fmus"); // getStringFromCharArray( FMUWorkingFolderCharArr );
     982             : 
     983             :         // Get and store the names of all FMUs in EnergyPlus data structure
     984           3 :         strippedFileName.allocate(state.dataExternalInterface->NumFMUObjects);
     985           3 :         fullFileName.allocate(state.dataExternalInterface->NumFMUObjects);
     986             : 
     987           3 :         auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     988           3 :         cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport";
     989           3 :         int NumAlphas = 0;  // Number of Alphas for each GetObjectItem call
     990           3 :         int NumNumbers = 0; // Number of Numbers for each GetObjectItem call
     991           3 :         int IOStatus = 0;   // Used in GetObjectItem
     992           6 :         for (int Loop = 1; Loop <= state.dataExternalInterface->NumFMUObjects; ++Loop) {
     993           9 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     994             :                                                                      cCurrentModuleObject,
     995             :                                                                      Loop,
     996           3 :                                                                      state.dataIPShortCut->cAlphaArgs,
     997             :                                                                      NumAlphas,
     998           3 :                                                                      state.dataIPShortCut->rNumericArgs,
     999             :                                                                      NumNumbers,
    1000             :                                                                      IOStatus,
    1001             :                                                                      _,
    1002             :                                                                      _,
    1003           3 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    1004           3 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    1005             :             // Get the FMU name
    1006           3 :             state.dataExternalInterface->FMU(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
    1007             : 
    1008           3 :             fs::path inputPath = FileSystem::makeNativePath(state.dataExternalInterface->FMU(Loop).Name);
    1009             : 
    1010           6 :             std::string contextString = cCurrentModuleObject + ", " + state.dataIPShortCut->cAlphaFieldNames(1) + ": ";
    1011             : 
    1012           3 :             tempFullFilePath = DataSystemVariables::CheckForActualFilePath(state, inputPath, contextString);
    1013           3 :             if (!tempFullFilePath.empty()) {
    1014             : 
    1015             :                 // TODO: eliminate this old block once confident
    1016           3 :                 std::string::size_type pos = index(state.dataExternalInterface->FMU(Loop).Name, DataStringGlobals::pathChar, true); // look backwards
    1017           3 :                 if (pos != std::string::npos) {
    1018           0 :                     strippedFileName(Loop) = state.dataExternalInterface->FMU(Loop).Name.substr(pos + 1);
    1019             :                 } else { // pos == 0, look for alt path char
    1020           3 :                     pos = index(state.dataExternalInterface->FMU(Loop).Name, DataStringGlobals::altpathChar, true); // look backwards
    1021           3 :                     if (pos != std::string::npos) {
    1022           3 :                         strippedFileName(Loop) = state.dataExternalInterface->FMU(Loop).Name.substr(pos + 1);
    1023             :                     } else {
    1024           0 :                         strippedFileName(Loop) = state.dataExternalInterface->FMU(Loop).Name;
    1025             :                     }
    1026             :                 }
    1027           3 :                 fullFileName(Loop) = FileSystem::toString(tempFullFilePath);
    1028             :             } else {
    1029           0 :                 state.dataExternalInterface->ErrorsFound = true;
    1030             :             }
    1031             :             // Get fmu time out
    1032           3 :             state.dataExternalInterface->FMU(Loop).TimeOut = state.dataIPShortCut->rNumericArgs(1);
    1033             :             // Get fmu logging on
    1034           3 :             state.dataExternalInterface->FMU(Loop).LoggingOn = state.dataIPShortCut->rNumericArgs(2);
    1035           3 :         }
    1036             : 
    1037             :         // check for dups that aren't the same file
    1038             :         // this is windows code...
    1039             :         // So this check that if I entered two different things and get the same end filename, then it's wrong?
    1040           6 :         for (int j = 1; j <= state.dataExternalInterface->NumFMUObjects; ++j) {
    1041           3 :             for (int k = 2; k <= state.dataExternalInterface->NumFMUObjects; ++k) {
    1042           0 :                 if (!Util::SameString(strippedFileName(j), strippedFileName(k))) continue;
    1043             :                 // base file names are the same
    1044           0 :                 if (Util::SameString(fullFileName(j), fullFileName(k))) continue;
    1045           0 :                 ShowSevereError(state, "ExternalInterface/InitExternalInterfaceFMUImport:");
    1046           0 :                 ShowContinueError(state, "duplicate file names (but not same file) entered.");
    1047           0 :                 ShowContinueError(state, format("...entered file name=\"{}\"", state.dataExternalInterface->FMU(j).Name));
    1048           0 :                 ShowContinueError(state, format("...   full file name=\"{}\"", fullFileName(j)));
    1049           0 :                 ShowContinueError(state, format("...entered file name=\"{}\"", state.dataExternalInterface->FMU(k).Name));
    1050           0 :                 ShowContinueError(state, format("...   full file name=\"{}\"", fullFileName(k)));
    1051           0 :                 ShowContinueError(state, "...name collision but not same file name.");
    1052           0 :                 state.dataExternalInterface->ErrorsFound = true;
    1053             :             }
    1054             :         }
    1055             : 
    1056           3 :         if (state.dataExternalInterface->ErrorsFound) {
    1057           0 :             strippedFileName.deallocate();
    1058           0 :             fullFileName.deallocate();
    1059           0 :             StopExternalInterfaceIfError(state);
    1060             :         }
    1061             : 
    1062             :         // get the names of the input variables each state.dataExternalInterface->FMU(and the names of the
    1063             :         // corresponding output variables in EnergyPlus --).
    1064           3 :         cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport:From:Variable";
    1065           3 :         int NumFMUInputVariables = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    1066             :         // Determine the number of instances for each FMUs
    1067           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1068           3 :             std::string Name_OLD = "";
    1069           3 :             int j = 1;
    1070           3 :             int k = 1;
    1071           3 :             state.dataExternalInterface->FMU(i).Instance.allocate(NumFMUInputVariables);
    1072           3 :             state.dataExternalInterface->checkInstanceName.allocate(NumFMUInputVariables);
    1073          11 :             for (int l = 1; l <= NumFMUInputVariables; ++l) {
    1074          24 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1075             :                                                                          cCurrentModuleObject,
    1076             :                                                                          l,
    1077           8 :                                                                          state.dataIPShortCut->cAlphaArgs,
    1078             :                                                                          NumAlphas,
    1079           8 :                                                                          state.dataIPShortCut->rNumericArgs,
    1080             :                                                                          NumNumbers,
    1081             :                                                                          IOStatus,
    1082             :                                                                          _,
    1083             :                                                                          _,
    1084           8 :                                                                          state.dataIPShortCut->cAlphaFieldNames,
    1085           8 :                                                                          state.dataIPShortCut->cNumericFieldNames);
    1086           8 :                 if (Util::SameString(state.dataIPShortCut->cAlphaArgs(3), state.dataExternalInterface->FMU(i).Name)) {
    1087           8 :                     std::string Name_NEW = state.dataIPShortCut->cAlphaArgs(4);
    1088           8 :                     if (!Util::SameString(Name_OLD, Name_NEW)) {
    1089           3 :                         int FOUND = Util::FindItem(Name_NEW, state.dataExternalInterface->checkInstanceName);
    1090           3 :                         if (FOUND == 0) {
    1091           3 :                             state.dataExternalInterface->checkInstanceName(l).Name = Name_NEW;
    1092           3 :                             state.dataExternalInterface->FMU(i).NumInstances = j;
    1093           3 :                             state.dataExternalInterface->FMU(i).Instance(j).Name = Name_NEW;
    1094           3 :                             ++j;
    1095           3 :                             Name_OLD = Name_NEW;
    1096             :                         }
    1097             :                     }
    1098           8 :                     state.dataExternalInterface->FMU(i).TotNumInputVariablesInIDF = k;
    1099           8 :                     ++k;
    1100           8 :                 }
    1101             :             }
    1102           3 :             state.dataExternalInterface->checkInstanceName.deallocate();
    1103           3 :         }
    1104             : 
    1105           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1106           3 :             if (state.dataExternalInterface->FMU(i).NumInstances == 0) {
    1107           0 :                 ShowSevereError(
    1108           0 :                     state, format("ExternalInterface/InitExternalInterfaceFMUImport: The FMU \"{}\" does", state.dataExternalInterface->FMU(i).Name));
    1109           0 :                 ShowContinueError(state, "not have any instances or any input variable. An FMU should have at least one instance");
    1110           0 :                 ShowContinueError(state, "or one input variable defined in input file. Check FMU object in the input file.");
    1111           0 :                 state.dataExternalInterface->ErrorsFound = true;
    1112           0 :                 StopExternalInterfaceIfError(state);
    1113             :             }
    1114           3 :             if (NumFMUInputVariables > 0 && state.dataExternalInterface->FMU(i).TotNumInputVariablesInIDF == 0) {
    1115           0 :                 ShowWarningError(state, format("InitExternalInterfaceFMUImport: The FMU \"{}\"", state.dataExternalInterface->FMU(i).Name));
    1116           0 :                 ShowContinueError(state, "is defined but has no input variables.");
    1117           0 :                 ShowContinueError(state, "Check the input field of the corresponding object");
    1118           0 :                 ShowContinueError(state, "ExternalInterface:FunctionalMockupUnitImport:From:Variable.");
    1119             :             }
    1120             :         }
    1121             : 
    1122             :         // write output folder where FMUs will be unpacked later on.
    1123           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1124           6 :             for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1125           3 :                 state.dataExternalInterface->FMU(i).Instance(j).WorkingFolder =
    1126           6 :                     state.dataExternalInterface->FMURootWorkingFolder /
    1127           9 :                     fs::path(strippedFileName(i) + '_' + state.dataExternalInterface->FMU(i).Instance(j).Name);
    1128             :             }
    1129             :         }
    1130             : 
    1131             :         // parse the fmu defined in the idf using the fmuUnpack.
    1132           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1133           6 :             for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1134             :                 // get the length of working folder trimmed
    1135           3 :                 std::string const workingFolderStr = FileSystem::toString(state.dataExternalInterface->FMU(i).Instance(j).WorkingFolder);
    1136           3 :                 state.dataExternalInterface->FMU(i).Instance(j).LenWorkingFolder = workingFolderStr.length();
    1137             :                 // unpack fmus
    1138             :                 // preprocess arguments for library call
    1139             :                 {
    1140           3 :                     std::vector<char> fullFileNameArr(getCharArrayFromString(fullFileName(i)));
    1141           3 :                     std::vector<char> workingFolderArr(getCharArrayFromString(workingFolderStr));
    1142           3 :                     int lenFileName(len(fullFileName(i)));
    1143             : 
    1144             :                     // make the library call
    1145           3 :                     int retVal = fmiEPlusUnpack(
    1146           3 :                         &fullFileNameArr[0], &workingFolderArr[0], &lenFileName, &state.dataExternalInterface->FMU(i).Instance(j).LenWorkingFolder);
    1147             : 
    1148           3 :                     if (retVal != 0) {
    1149           0 :                         ShowSevereError(state, "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to");
    1150           0 :                         ShowContinueError(state, format("unpack the FMU \"{}\".", state.dataExternalInterface->FMU(i).Name));
    1151           0 :                         ShowContinueError(state, "Check if the FMU exists. Also check if the FMU folder is not write protected.");
    1152           0 :                         state.dataExternalInterface->ErrorsFound = true;
    1153           0 :                         StopExternalInterfaceIfError(state);
    1154             :                     }
    1155           3 :                 }
    1156             : 
    1157             :                 {
    1158             :                     // determine modelID and modelGUID of all FMU instances
    1159             :                     // preprocess arguments for library call
    1160           3 :                     std::vector<char> workingFolderArr(getCharArrayFromString(workingFolderStr));
    1161             : 
    1162             :                     // make the library call
    1163           3 :                     state.dataExternalInterface->FMU(i).Instance(j).Index =
    1164           3 :                         model_ID_GUID((char *)state.dataExternalInterface->FMU(i).Instance(j).Name.c_str(),
    1165           3 :                                       &workingFolderArr[0],
    1166           3 :                                       &state.dataExternalInterface->FMU(i).Instance(j).LenWorkingFolder,
    1167           3 :                                       &state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInFMU,
    1168           3 :                                       &state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInFMU);
    1169             : 
    1170           3 :                     if (state.dataExternalInterface->FMU(i).Instance(j).Index < 0) {
    1171           0 :                         ShowSevereError(state, "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to");
    1172           0 :                         ShowContinueError(state, "get the model ID and model GUID");
    1173           0 :                         ShowContinueError(state,
    1174           0 :                                           format("of instance \"{}\" of FMU \"{}\".",
    1175           0 :                                                  state.dataExternalInterface->FMU(i).Instance(j).Name,
    1176           0 :                                                  state.dataExternalInterface->FMU(i).Name));
    1177           0 :                         ShowContinueError(state, "Check if modelDescription.xml exists in the folder where the FMU has been unpacked.");
    1178           0 :                         state.dataExternalInterface->ErrorsFound = true;
    1179           0 :                         StopExternalInterfaceIfError(state);
    1180             :                     }
    1181           3 :                 }
    1182             : 
    1183             :                 {
    1184             :                     // get the path to the binaries
    1185             :                     // preprocess args for library call
    1186           3 :                     std::vector<char> workingFolderArr(getCharArrayFromString(workingFolderStr));
    1187             :                     // Reserve some space in the string, becasue addLibPathCurrentWorkflowFolder doesn't allocate memory for the
    1188             :                     // workingFolderWithLibArr Note: you can't call str.resize(str.length() + 91) because the conversion to std::vector<char> will
    1189             :                     // find the null terminator and so it will have no effect
    1190             :                     std::string reservedString =
    1191           3 :                         workingFolderStr + "                                                                                           ";
    1192           3 :                     std::vector<char> workingFolderWithLibArr(getCharArrayFromString(reservedString));
    1193             : 
    1194             :                     // make the library call
    1195           3 :                     int retValfmiPathLib = addLibPathCurrentWorkingFolder(&workingFolderWithLibArr[0],
    1196           3 :                                                                           &workingFolderArr[0],
    1197           3 :                                                                           &state.dataExternalInterface->FMU(i).Instance(j).LenWorkingFolder,
    1198           3 :                                                                           &state.dataExternalInterface->FMU(i).Instance(j).Index);
    1199             : 
    1200             :                     // post process args in case they are used later
    1201           3 :                     state.dataExternalInterface->FMU(i).Instance(j).WorkingFolder_wLib =
    1202           6 :                         fs::path(trim(getStringFromCharArray(workingFolderWithLibArr)));
    1203             : 
    1204           3 :                     if (retValfmiPathLib != 0) {
    1205           0 :                         ShowSevereError(state, "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to");
    1206           0 :                         ShowContinueError(state, "get the path to the binaries of instance");
    1207           0 :                         ShowContinueError(state,
    1208           0 :                                           format("\"{}\" of FMU \"{}\".",
    1209           0 :                                                  state.dataExternalInterface->FMU(i).Instance(j).Name,
    1210           0 :                                                  state.dataExternalInterface->FMU(i).Name));
    1211           0 :                         ShowContinueError(state, "Check if binaries folder exists where the FMU has been unpacked.");
    1212           0 :                         state.dataExternalInterface->ErrorsFound = true;
    1213           0 :                         StopExternalInterfaceIfError(state);
    1214             :                     }
    1215             : 
    1216             :                     // get the length of the working folder with libraries
    1217           3 :                     state.dataExternalInterface->FMU(i).Instance(j).LenWorkingFolder_wLib =
    1218           6 :                         FileSystem::toString(state.dataExternalInterface->FMU(i).Instance(j).WorkingFolder_wLib).length();
    1219           3 :                 }
    1220             : 
    1221             :                 {
    1222             :                     // determine the FMI version
    1223             :                     // preprocess args for library call
    1224             :                     std::vector<char> workingFolderWithLibArr(
    1225           3 :                         getCharArrayFromString(FileSystem::toString(state.dataExternalInterface->FMU(i).Instance(j).WorkingFolder_wLib)));
    1226             :                     std::vector<char> VersionNumArr(
    1227           6 :                         getCharArrayFromString("    ")); // the version should only be 3 characters long, since for now we only handle "1.0"
    1228             : 
    1229             :                     // make the library call
    1230           3 :                     int retValfmiVersion = getfmiEPlusVersion(&workingFolderWithLibArr[0],
    1231           3 :                                                               &state.dataExternalInterface->FMU(i).Instance(j).LenWorkingFolder_wLib,
    1232           3 :                                                               &VersionNumArr[0],
    1233           3 :                                                               &state.dataExternalInterface->FMU(i).Instance(j).Index);
    1234             : 
    1235             :                     // post process in case args are used later
    1236           3 :                     state.dataExternalInterface->FMU(i).Instance(j).fmiVersionNumber = getStringFromCharArray(VersionNumArr);
    1237             : 
    1238           3 :                     if (retValfmiVersion != 0) {
    1239           0 :                         ShowSevereError(state, "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to");
    1240           0 :                         ShowContinueError(state, "load FMI functions library of instance");
    1241           0 :                         ShowContinueError(state,
    1242           0 :                                           format("\"{}\" of FMU \"{}\".",
    1243           0 :                                                  state.dataExternalInterface->FMU(i).Instance(j).Name,
    1244           0 :                                                  state.dataExternalInterface->FMU(i).Name));
    1245           0 :                         ShowContinueError(state, format("\"{}\".", state.dataExternalInterface->FMU(i).Instance(j).fmiVersionNumber));
    1246           0 :                         state.dataExternalInterface->ErrorsFound = true;
    1247           0 :                         StopExternalInterfaceIfError(state);
    1248             :                     }
    1249             : 
    1250           3 :                     if (state.dataExternalInterface->FMU(i).Instance(j).fmiVersionNumber.substr(0, 3) != "1.0") {
    1251           0 :                         ShowSevereError(state, "ExternalInterface/InitExternalInterfaceFMUImport: Error when getting version");
    1252           0 :                         ShowContinueError(state, format("number of instance \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).Name));
    1253           0 :                         ShowContinueError(state, format("of FMU \"{}\".", state.dataExternalInterface->FMU(i).Name));
    1254           0 :                         ShowContinueError(state,
    1255           0 :                                           format("The version number found (\"{}\")",
    1256           0 :                                                  state.dataExternalInterface->FMU(i).Instance(j).fmiVersionNumber.substr(0, 3)));
    1257           0 :                         ShowContinueError(state, "differs from version 1.0 which is currently supported.");
    1258           0 :                         state.dataExternalInterface->ErrorsFound = true;
    1259           0 :                         StopExternalInterfaceIfError(state);
    1260             :                     }
    1261           3 :                 }
    1262           3 :             }
    1263             :         }
    1264             : 
    1265           3 :         strippedFileName.deallocate();
    1266           3 :         fullFileName.deallocate();
    1267             : 
    1268           3 :         state.dataExternalInterface->UniqueFMUInputVarNames.reserve(static_cast<unsigned>(NumFMUInputVariables));
    1269           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1270           6 :             for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1271           3 :                 state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable.allocate(NumFMUInputVariables);
    1272           3 :                 state.dataExternalInterface->FMU(i).Instance(j).checkfmuInputVariable.allocate(NumFMUInputVariables);
    1273           3 :                 state.dataExternalInterface->UniqueFMUInputVarNames.clear();
    1274           3 :                 state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable.allocate(NumFMUInputVariables);
    1275           3 :                 int k = 1;
    1276          11 :                 for (int l = 1; l <= NumFMUInputVariables; ++l) {
    1277          24 :                     state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1278             :                                                                              cCurrentModuleObject,
    1279             :                                                                              l,
    1280           8 :                                                                              state.dataIPShortCut->cAlphaArgs,
    1281             :                                                                              NumAlphas,
    1282           8 :                                                                              state.dataIPShortCut->rNumericArgs,
    1283             :                                                                              NumNumbers,
    1284             :                                                                              IOStatus,
    1285             :                                                                              _,
    1286             :                                                                              _,
    1287           8 :                                                                              state.dataIPShortCut->cAlphaFieldNames,
    1288           8 :                                                                              state.dataIPShortCut->cNumericFieldNames);
    1289          16 :                     if (Util::SameString(state.dataIPShortCut->cAlphaArgs(3), state.dataExternalInterface->FMU(i).Name) &&
    1290           8 :                         Util::SameString(state.dataIPShortCut->cAlphaArgs(4), state.dataExternalInterface->FMU(i).Instance(j).Name)) {
    1291           8 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).Name = state.dataIPShortCut->cAlphaArgs(5);
    1292           8 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarKey = state.dataIPShortCut->cAlphaArgs(1);
    1293           8 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).Name = state.dataIPShortCut->cAlphaArgs(2);
    1294             :                         // verify whether we have duplicate FMU input variables in the idf
    1295           8 :                         GlobalNames::VerifyUniqueInterObjectName(state,
    1296           8 :                                                                  state.dataExternalInterface->UniqueFMUInputVarNames,
    1297           8 :                                                                  state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).Name,
    1298             :                                                                  cCurrentModuleObject,
    1299           8 :                                                                  state.dataExternalInterface->FMU(i).Instance(j).Name,
    1300           8 :                                                                  state.dataExternalInterface->ErrorsFound);
    1301             :                         //                            Util::VerifyName( state.dataExternalInterface->FMU( i ).Instance( j
    1302             :                         //                            ).fmuInputVariable(
    1303             :                         // k
    1304             :                         //).Name,  state.dataExternalInterface->FMU(
    1305             :                         // i
    1306             :                         //).Instance(
    1307             :                         // j
    1308             :                         //).checkfmuInputVariable, NumFMUInputVariables, IsNotOK, IsBlank, "The FMU input variable \"" +
    1309             :                         // state.dataExternalInterface->FMU( i ).Instance( j
    1310             :                         //).fmuInputVariable( k ).Name + "\" of instance \"" + state.dataExternalInterface->FMU( i ).Instance( j ).Name + "\" of FMU
    1311             :                         //\"" + state.dataExternalInterface->FMU( i ).Name + "\"
    1312             :                         // has duplicates. Please check the input file again and delete duplicated entries." );
    1313           8 :                         if (state.dataExternalInterface->ErrorsFound) {
    1314           0 :                             StopExternalInterfaceIfError(state);
    1315             :                         } else {
    1316           8 :                             state.dataExternalInterface->FMU(i).Instance(j).checkfmuInputVariable(k).Name =
    1317          16 :                                 state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).Name;
    1318             :                         }
    1319             : 
    1320             :                         // preprocess args for library call
    1321             :                         std::vector<char> inputVarNameArr(
    1322           8 :                             getCharArrayFromString(state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).Name));
    1323           8 :                         int inputVarNameLen(len(state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).Name));
    1324             : 
    1325             :                         // make the library call
    1326           8 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).ValueReference = getValueReferenceByNameFMUInputVariables(
    1327           8 :                             &inputVarNameArr[0], &inputVarNameLen, &state.dataExternalInterface->FMU(i).Instance(j).Index);
    1328             : 
    1329             :                         // postprocess args in case they are used later
    1330           8 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).Name = getStringFromCharArray(inputVarNameArr);
    1331             : 
    1332           8 :                         if (state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).ValueReference == -999) {
    1333           0 :                             ShowSevereError(state, "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to");
    1334           0 :                             ShowContinueError(state, "get the value reference of FMU input variable");
    1335           0 :                             ShowContinueError(state,
    1336           0 :                                               format("\"{}\" of instance \"{}\" of FMU",
    1337           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).Name,
    1338           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).Name));
    1339           0 :                             ShowContinueError(
    1340           0 :                                 state, format("of FMU \"{}\". Please check the name of input variable", state.dataExternalInterface->FMU(i).Name));
    1341           0 :                             ShowContinueError(state, "in the input file and in the modelDescription file.");
    1342           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1343           0 :                             StopExternalInterfaceIfError(state);
    1344             :                         }
    1345             : 
    1346           8 :                         if (state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).ValueReference == -1) {
    1347           0 :                             ShowSevereError(state, "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to");
    1348           0 :                             ShowContinueError(state, "get the value reference of FMU input variable");
    1349           0 :                             ShowContinueError(state,
    1350           0 :                                               format("\"{}\" of instance \"{}\" of FMU",
    1351           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).Name,
    1352           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).Name));
    1353           0 :                             ShowContinueError(
    1354           0 :                                 state, format("\"{}\". This variable is not an FMU input variable.", state.dataExternalInterface->FMU(i).Name));
    1355           0 :                             ShowContinueError(state, "Please check the causality of the variable in the modelDescription file.");
    1356           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1357           0 :                             StopExternalInterfaceIfError(state);
    1358             :                         }
    1359             : 
    1360             :                         // The next call expects an array, but a single item is passed
    1361             :                         // Therefore create a single item array here first
    1362           8 :                         Array1D_string tempSingleStringA(1, state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarKey);
    1363           8 :                         Array1D_string tempSingleStringB(1, state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).Name);
    1364             : 
    1365             :                         // Make the call with arrays
    1366           8 :                         GetReportVariableKey(state, tempSingleStringA, 1, tempSingleStringB, keyIndexes, varTypes);
    1367             : 
    1368             :                         // Then postprocess the array items back in case they changed
    1369           8 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarKey = tempSingleStringA(1);
    1370           8 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).Name = tempSingleStringB(1);
    1371             : 
    1372           8 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarIndex = keyIndexes(1);
    1373           8 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarType = varTypes(1);
    1374           8 :                         state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF = k;
    1375           8 :                         ++k;
    1376           8 :                     }
    1377             :                 }
    1378             : 
    1379           3 :                 if (NumFMUInputVariables > 0 && state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF == 0) {
    1380           0 :                     ShowWarningError(state,
    1381           0 :                                      format("InitExternalInterfaceFMUImport: The instance \"{}\" of FMU \"{}\"",
    1382           0 :                                             state.dataExternalInterface->FMU(i).Instance(j).Name,
    1383           0 :                                             state.dataExternalInterface->FMU(i).Name));
    1384           0 :                     ShowContinueError(state, "is defined but has no input variables. Check the input field of the");
    1385           0 :                     ShowContinueError(state, "corresponding object: ExternalInterface:FunctionalMockupUnitImport:From:Variable.");
    1386             :                 }
    1387             :             }
    1388             :         }
    1389             : 
    1390           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1391           6 :             for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1392             :                 // check whether the number of input variables in fmu is bigger than in the idf
    1393           3 :                 if (state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInFMU >
    1394           3 :                     state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF) {
    1395           0 :                     ShowWarningError(state,
    1396           0 :                                      format("InitExternalInterfaceFMUImport: The number of input variables defined in input file ({})",
    1397           0 :                                             state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF));
    1398           0 :                     ShowContinueError(state,
    1399           0 :                                       format("of instance \"{}\" of FMU \"{}\" is less than the number of input variables",
    1400           0 :                                              state.dataExternalInterface->FMU(i).Instance(j).Name,
    1401           0 :                                              state.dataExternalInterface->FMU(i).Name));
    1402           0 :                     ShowContinueError(
    1403           0 :                         state, format("in the modelDescription file ({}).", state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInFMU));
    1404           0 :                     ShowContinueError(state, "Check the input file and the modelDescription file again.");
    1405             :                 }
    1406             :                 // check whether the number of input variables in fmu is less than in the idf
    1407           3 :                 if (state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInFMU <
    1408           3 :                     state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF) {
    1409           0 :                     ShowWarningError(state,
    1410           0 :                                      format("InitExternalInterfaceFMUImport: The number of input variables defined in input file ({})",
    1411           0 :                                             state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF));
    1412           0 :                     ShowContinueError(state,
    1413           0 :                                       format("of instance \"{}\" of FMU \"{}\" is bigger than the number of input variables",
    1414           0 :                                              state.dataExternalInterface->FMU(i).Instance(j).Name,
    1415           0 :                                              state.dataExternalInterface->FMU(i).Name));
    1416           0 :                     ShowContinueError(
    1417           0 :                         state, format("in the modelDescription file ({}).", state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInFMU));
    1418           0 :                     ShowContinueError(state, "Check the input file and the modelDescription file again.");
    1419             :                 }
    1420             :             }
    1421             :         }
    1422             : 
    1423             :         // get the names of the output variables each fmu (and the names of the
    1424             :         // corresponding input variables in EnergyPlus -- schedule).
    1425           3 :         cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport:To:Schedule";
    1426           3 :         NumFMUInputVariables = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    1427             : 
    1428           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1429           3 :             int j = 1;
    1430           5 :             for (int k = 1; k <= NumFMUInputVariables; ++k) {
    1431           6 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1432             :                                                                          cCurrentModuleObject,
    1433             :                                                                          k,
    1434           2 :                                                                          state.dataIPShortCut->cAlphaArgs,
    1435             :                                                                          NumAlphas,
    1436           2 :                                                                          state.dataIPShortCut->rNumericArgs,
    1437             :                                                                          NumNumbers,
    1438             :                                                                          IOStatus,
    1439             :                                                                          _,
    1440             :                                                                          _,
    1441           2 :                                                                          state.dataIPShortCut->cAlphaFieldNames,
    1442           2 :                                                                          state.dataIPShortCut->cNumericFieldNames);
    1443           2 :                 if (Util::SameString(state.dataIPShortCut->cAlphaArgs(3), state.dataExternalInterface->FMU(i).Name)) {
    1444           2 :                     state.dataExternalInterface->FMU(i).TotNumOutputVariablesSchedule = j;
    1445           2 :                     ++j;
    1446             :                 }
    1447             :             }
    1448             :         }
    1449             : 
    1450           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1451           6 :             for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1452           3 :                 state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule.allocate(NumFMUInputVariables);
    1453           3 :                 state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableSchedule.allocate(NumFMUInputVariables);
    1454           3 :                 int k = 1;
    1455           5 :                 for (int l = 1; l <= NumFMUInputVariables; ++l) {
    1456           6 :                     state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1457             :                                                                              cCurrentModuleObject,
    1458             :                                                                              l,
    1459           2 :                                                                              state.dataIPShortCut->cAlphaArgs,
    1460             :                                                                              NumAlphas,
    1461           2 :                                                                              state.dataIPShortCut->rNumericArgs,
    1462             :                                                                              NumNumbers,
    1463             :                                                                              IOStatus,
    1464             :                                                                              _,
    1465             :                                                                              _,
    1466           2 :                                                                              state.dataIPShortCut->cAlphaFieldNames,
    1467           2 :                                                                              state.dataIPShortCut->cNumericFieldNames);
    1468           4 :                     if (Util::SameString(state.dataIPShortCut->cAlphaArgs(3), state.dataExternalInterface->FMU(i).Name) &&
    1469           2 :                         Util::SameString(state.dataIPShortCut->cAlphaArgs(4), state.dataExternalInterface->FMU(i).Instance(j).Name)) {
    1470           2 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).Name = state.dataIPShortCut->cAlphaArgs(5);
    1471           2 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableSchedule(k).Name = state.dataIPShortCut->cAlphaArgs(1);
    1472           2 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableSchedule(k).InitialValue =
    1473           2 :                             state.dataIPShortCut->rNumericArgs(1);
    1474             : 
    1475             :                         // get the value reference by using the FMU name and the variable name.
    1476             : 
    1477             :                         // preprocess the arguments before the following library call
    1478             :                         std::vector<char> NameCharArr(
    1479           2 :                             getCharArrayFromString(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).Name));
    1480           2 :                         int lengthVar(len(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).Name));
    1481             : 
    1482             :                         // make the library call
    1483           2 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).ValueReference =
    1484           2 :                             getValueReferenceByNameFMUOutputVariables(
    1485           2 :                                 &NameCharArr[0], &lengthVar, &state.dataExternalInterface->FMU(i).Instance(j).Index);
    1486             : 
    1487             :                         // postprocess the arguments after the library call in case they are changed and used later
    1488           2 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).Name = getStringFromCharArray(NameCharArr);
    1489             : 
    1490           2 :                         if (state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).ValueReference == -999) {
    1491           0 :                             ShowSevereError(state,
    1492             :                                             "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to get the value reference of "
    1493             :                                             "the FMU output variable");
    1494           0 :                             ShowContinueError(state,
    1495           0 :                                               format("\"{}\" of instance \"{}\"",
    1496           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).Name,
    1497           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).Name));
    1498           0 :                             ShowContinueError(state,
    1499           0 :                                               format("of FMU \"{}\" that will be mapped to a schedule.", state.dataExternalInterface->FMU(i).Name));
    1500           0 :                             ShowContinueError(state, "Please check the name of output variables in the input file and");
    1501           0 :                             ShowContinueError(state, "in the modelDescription file.");
    1502           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1503           0 :                             StopExternalInterfaceIfError(state);
    1504             :                         }
    1505             : 
    1506           2 :                         if (state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).ValueReference == -1) {
    1507           0 :                             ShowSevereError(state,
    1508             :                                             "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to get the value reference of "
    1509             :                                             "the FMU output variable");
    1510           0 :                             ShowContinueError(state,
    1511           0 :                                               format("\"{}\" of instance \"{}\"",
    1512           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).Name,
    1513           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).Name));
    1514           0 :                             ShowContinueError(state,
    1515           0 :                                               format("of FMU \"{}\" that will be mapped to a schedule.", state.dataExternalInterface->FMU(i).Name));
    1516           0 :                             ShowContinueError(state, "This variable is not an FMU output variable.");
    1517           0 :                             ShowContinueError(state, "Please check the causality of the variable in the modelDescription file.");
    1518           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1519           0 :                             StopExternalInterfaceIfError(state);
    1520             :                         }
    1521             : 
    1522           2 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableSchedule(k).VarIndex = ScheduleManager::GetDayScheduleIndex(
    1523           2 :                             state, state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableSchedule(k).Name);
    1524           2 :                         state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesSchedule = k;
    1525           2 :                         if (state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableSchedule(k).VarIndex <= 0) {
    1526           0 :                             ShowSevereError(state,
    1527           0 :                                             format("ExternalInterface/InitExternalInterfaceFMUImport:declares variable \"{}\",",
    1528           0 :                                                    state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableSchedule(k).Name));
    1529           0 :                             ShowContinueError(state, "but variable is not a schedule variable.");
    1530           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1531           0 :                             StopExternalInterfaceIfError(state);
    1532             :                         }
    1533           2 :                         ++k;
    1534           2 :                     }
    1535             :                 }
    1536             :             }
    1537             :         }
    1538             : 
    1539             :         // get the names of the output variables each fmu (and the names of the
    1540             :         // corresponding input variables in EnergyPlus -- variable).
    1541           3 :         cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport:To:Variable";
    1542           3 :         NumFMUInputVariables = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    1543             : 
    1544           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1545           3 :             int j = 1;
    1546           4 :             for (int k = 1; k <= NumFMUInputVariables; ++k) {
    1547           3 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1548             :                                                                          cCurrentModuleObject,
    1549             :                                                                          k,
    1550           1 :                                                                          state.dataIPShortCut->cAlphaArgs,
    1551             :                                                                          NumAlphas,
    1552           1 :                                                                          state.dataIPShortCut->rNumericArgs,
    1553             :                                                                          NumNumbers,
    1554             :                                                                          IOStatus,
    1555             :                                                                          _,
    1556             :                                                                          _,
    1557           1 :                                                                          state.dataIPShortCut->cAlphaFieldNames,
    1558           1 :                                                                          state.dataIPShortCut->cNumericFieldNames);
    1559           1 :                 if (Util::SameString(state.dataIPShortCut->cAlphaArgs(2), state.dataExternalInterface->FMU(i).Name)) {
    1560           1 :                     state.dataExternalInterface->FMU(i).TotNumOutputVariablesVariable = j;
    1561           1 :                     ++j;
    1562             :                 }
    1563             :             }
    1564             :         }
    1565             : 
    1566           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1567           6 :             for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1568           3 :                 state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable.allocate(NumFMUInputVariables);
    1569           3 :                 state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableVariable.allocate(NumFMUInputVariables);
    1570           3 :                 int k = 1;
    1571           4 :                 for (int l = 1; l <= NumFMUInputVariables; ++l) {
    1572           3 :                     state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1573             :                                                                              cCurrentModuleObject,
    1574             :                                                                              l,
    1575           1 :                                                                              state.dataIPShortCut->cAlphaArgs,
    1576             :                                                                              NumAlphas,
    1577           1 :                                                                              state.dataIPShortCut->rNumericArgs,
    1578             :                                                                              NumNumbers,
    1579             :                                                                              IOStatus,
    1580             :                                                                              _,
    1581             :                                                                              _,
    1582           1 :                                                                              state.dataIPShortCut->cAlphaFieldNames,
    1583           1 :                                                                              state.dataIPShortCut->cNumericFieldNames);
    1584           2 :                     if (Util::SameString(state.dataIPShortCut->cAlphaArgs(2), state.dataExternalInterface->FMU(i).Name) &&
    1585           1 :                         Util::SameString(state.dataIPShortCut->cAlphaArgs(3), state.dataExternalInterface->FMU(i).Instance(j).Name)) {
    1586           1 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).Name = state.dataIPShortCut->cAlphaArgs(4);
    1587           1 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableVariable(k).Name = state.dataIPShortCut->cAlphaArgs(1);
    1588             : 
    1589             :                         // get the value reference by using the FMU name and the variable name.
    1590             :                         std::vector<char> NameCharArr(
    1591           1 :                             getCharArrayFromString(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).Name));
    1592           1 :                         int tempLength(len(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).Name));
    1593           1 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).ValueReference =
    1594           1 :                             getValueReferenceByNameFMUOutputVariables(
    1595           1 :                                 &NameCharArr[0], &tempLength, &state.dataExternalInterface->FMU(i).Instance(j).Index);
    1596             :                         // state.dataExternalInterface->FMU( i ).Instance( j ).fmuOutputVariableVariable( k ).Name = getStringFromCharArray(
    1597             :                         // NameCharArr );
    1598             : 
    1599           1 :                         if (state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).ValueReference == -999) {
    1600           0 :                             ShowSevereError(state,
    1601             :                                             "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to get the value reference of "
    1602             :                                             "the FMU output variable");
    1603           0 :                             ShowContinueError(state,
    1604           0 :                                               format("\"{}\" of instance \"{}\"",
    1605           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).Name,
    1606           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).Name));
    1607           0 :                             ShowContinueError(state,
    1608           0 :                                               format("of FMU \"{}\" that will be mapped to a variable.", state.dataExternalInterface->FMU(i).Name));
    1609           0 :                             ShowContinueError(state, "Please check the name of output variables in the input file and in the modelDescription file.");
    1610           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1611           0 :                             StopExternalInterfaceIfError(state);
    1612             :                         }
    1613             : 
    1614           1 :                         if (state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).ValueReference == -1) {
    1615           0 :                             ShowSevereError(state,
    1616             :                                             "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to get the value reference of "
    1617             :                                             "the FMU output variable");
    1618           0 :                             ShowContinueError(state,
    1619           0 :                                               format("\"{}\" of instance \"{}\"",
    1620           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).Name,
    1621           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).Name));
    1622           0 :                             ShowContinueError(state,
    1623           0 :                                               format("of FMU \"{}\" that will be mapped to a variable.", state.dataExternalInterface->FMU(i).Name));
    1624           0 :                             ShowContinueError(state,
    1625             :                                               "This variable is not an FMU output variable. Please check the causality of the variable in the "
    1626             :                                               "modelDescription file.");
    1627           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1628           0 :                             StopExternalInterfaceIfError(state);
    1629             :                         }
    1630             : 
    1631           1 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableVariable(k).VarIndex =
    1632           1 :                             RuntimeLanguageProcessor::FindEMSVariable(
    1633           1 :                                 state, state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableVariable(k).Name, 0);
    1634           1 :                         state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesVariable = k;
    1635           1 :                         if (state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableVariable(k).VarIndex <= 0) {
    1636           0 :                             ShowSevereError(state,
    1637           0 :                                             format("ExternalInterface/InitExternalInterfaceFMUImport:declares variable \"{}\",",
    1638           0 :                                                    state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableVariable(k).Name));
    1639           0 :                             ShowContinueError(state, "but variable is not an EMS variable.");
    1640           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1641           0 :                             StopExternalInterfaceIfError(state);
    1642             :                         }
    1643           1 :                         ++k;
    1644           1 :                     }
    1645             :                 }
    1646           3 :                 if (state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesVariable >= 1) {
    1647           1 :                     state.dataExternalInterface->useEMS = true;
    1648             :                 }
    1649             :             }
    1650             :         }
    1651             : 
    1652             :         // get the names of the output variables each fmu (and the names of the
    1653             :         // corresponding input variables in EnergyPlus -- actuator).
    1654           3 :         cCurrentModuleObject = "ExternalInterface:FunctionalMockupUnitImport:To:Actuator";
    1655           3 :         NumFMUInputVariables = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    1656             : 
    1657           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1658           3 :             int j = 1;
    1659           4 :             for (int k = 1; k <= NumFMUInputVariables; ++k) {
    1660           3 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1661             :                                                                          cCurrentModuleObject,
    1662             :                                                                          k,
    1663           1 :                                                                          state.dataIPShortCut->cAlphaArgs,
    1664             :                                                                          NumAlphas,
    1665           1 :                                                                          state.dataIPShortCut->rNumericArgs,
    1666             :                                                                          NumNumbers,
    1667             :                                                                          IOStatus,
    1668             :                                                                          _,
    1669             :                                                                          _,
    1670           1 :                                                                          state.dataIPShortCut->cAlphaFieldNames,
    1671           1 :                                                                          state.dataIPShortCut->cNumericFieldNames);
    1672           1 :                 if (Util::SameString(state.dataIPShortCut->cAlphaArgs(5), state.dataExternalInterface->FMU(i).Name)) {
    1673           1 :                     state.dataExternalInterface->FMU(i).TotNumOutputVariablesActuator = j;
    1674           1 :                     ++j;
    1675             :                 }
    1676             :             }
    1677             :         }
    1678             : 
    1679           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1680           6 :             for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1681           3 :                 state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator.allocate(NumFMUInputVariables);
    1682           3 :                 state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableActuator.allocate(NumFMUInputVariables);
    1683           3 :                 int k = 1;
    1684           4 :                 for (int l = 1; l <= NumFMUInputVariables; ++l) {
    1685           3 :                     state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1686             :                                                                              cCurrentModuleObject,
    1687             :                                                                              l,
    1688           1 :                                                                              state.dataIPShortCut->cAlphaArgs,
    1689             :                                                                              NumAlphas,
    1690           1 :                                                                              state.dataIPShortCut->rNumericArgs,
    1691             :                                                                              NumNumbers,
    1692             :                                                                              IOStatus,
    1693             :                                                                              _,
    1694             :                                                                              _,
    1695           1 :                                                                              state.dataIPShortCut->cAlphaFieldNames,
    1696           1 :                                                                              state.dataIPShortCut->cNumericFieldNames);
    1697           2 :                     if (Util::SameString(state.dataIPShortCut->cAlphaArgs(5), state.dataExternalInterface->FMU(i).Name) &&
    1698           1 :                         Util::SameString(state.dataIPShortCut->cAlphaArgs(6), state.dataExternalInterface->FMU(i).Instance(j).Name)) {
    1699           1 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).Name = state.dataIPShortCut->cAlphaArgs(7);
    1700           1 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableActuator(k).Name = state.dataIPShortCut->cAlphaArgs(1);
    1701             : 
    1702             :                         // get the value reference by using the FMU name and the variable name.
    1703             :                         std::vector<char> tempNameArr(
    1704           1 :                             getCharArrayFromString(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).Name));
    1705           1 :                         int tempLength(len(state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).Name));
    1706           1 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).ValueReference =
    1707           1 :                             getValueReferenceByNameFMUOutputVariables(
    1708           1 :                                 &tempNameArr[0], &tempLength, &state.dataExternalInterface->FMU(i).Instance(j).Index);
    1709             :                         // state.dataExternalInterface->FMU( i ).Instance( j ).fmuOutputVariableActuator( k ).Name = getStringFromCharArray(
    1710             :                         // tempNameArr );
    1711             : 
    1712           1 :                         if (state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).ValueReference == -999) {
    1713           0 :                             ShowSevereError(state,
    1714             :                                             "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to get the value reference of "
    1715             :                                             "the FMU output variable");
    1716           0 :                             ShowContinueError(state,
    1717           0 :                                               format("\"{}\" of instance \"{}\"",
    1718           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).Name,
    1719           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).Name));
    1720           0 :                             ShowContinueError(state,
    1721           0 :                                               format("of FMU \"{}\" that will be mapped to an actuator.", state.dataExternalInterface->FMU(i).Name));
    1722           0 :                             ShowContinueError(state, "Please check the name of output variables in the input file and in the modelDescription file.");
    1723           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1724           0 :                             StopExternalInterfaceIfError(state);
    1725             :                         }
    1726             : 
    1727           1 :                         if (state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).ValueReference == -1) {
    1728           0 :                             ShowSevereError(state,
    1729             :                                             "ExternalInterface/InitExternalInterfaceFMUImport: Error when trying to get the value reference of "
    1730             :                                             "the FMU output variable");
    1731           0 :                             ShowContinueError(state,
    1732           0 :                                               format("\"{}\" of instance \"{}\"",
    1733           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).Name,
    1734           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).Name));
    1735           0 :                             ShowContinueError(state,
    1736           0 :                                               format("of FMU \"{}\" that will be mapped to an actuator.", state.dataExternalInterface->FMU(i).Name));
    1737           0 :                             ShowContinueError(state,
    1738             :                                               "This variable is not an FMU output variable. Please check the causality of the variable in the "
    1739             :                                               "modelDescription file.");
    1740           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1741           0 :                             StopExternalInterfaceIfError(state);
    1742             :                         }
    1743             : 
    1744           1 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableActuator(k).VarIndex =
    1745           1 :                             RuntimeLanguageProcessor::FindEMSVariable(
    1746           1 :                                 state, state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableActuator(k).Name, 0);
    1747           1 :                         state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesActuator = k;
    1748           1 :                         if (state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableActuator(k).VarIndex <= 0) {
    1749           0 :                             ShowSevereError(state,
    1750           0 :                                             format("ExternalInterface/InitExternalInterfaceFMUImport:declares variable \"{}\",",
    1751           0 :                                                    state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableActuator(k).Name));
    1752           0 :                             ShowContinueError(state, "but variable is not an EMS variable.");
    1753           0 :                             state.dataExternalInterface->ErrorsFound = true;
    1754           0 :                             StopExternalInterfaceIfError(state);
    1755             :                         }
    1756           1 :                         ++k;
    1757           1 :                     }
    1758             :                 }
    1759             :                 // set the flag state.dataExternalInterface->useEMS to true. This will be used then to update the erl variables in erl data structure
    1760           3 :                 if (state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesActuator >= 1) {
    1761           1 :                     state.dataExternalInterface->useEMS = true;
    1762             :                 }
    1763             :             }
    1764             :         }
    1765             : 
    1766             :         // parse the fmu defined in the idf using the fmuUnpack with the flag --unpack.
    1767           6 :         for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1768           6 :             for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1769           3 :                 state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInIDF =
    1770           3 :                     state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesSchedule +
    1771           3 :                     state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesVariable +
    1772           3 :                     state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesActuator;
    1773             :                 // check whether the number of output variables in fmu is bigger than in the idf
    1774           3 :                 if (state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInFMU >
    1775           3 :                     state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInIDF) {
    1776           0 :                     ShowWarningError(state,
    1777           0 :                                      format("InitExternalInterfaceFMUImport: The number of output variables defined in input file ({})",
    1778           0 :                                             state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInIDF));
    1779           0 :                     ShowContinueError(state,
    1780           0 :                                       format("of instance \"{}\" of FMU \"{}\" is less than the number of output variables",
    1781           0 :                                              state.dataExternalInterface->FMU(i).Instance(j).Name,
    1782           0 :                                              state.dataExternalInterface->FMU(i).Name));
    1783           0 :                     ShowContinueError(
    1784           0 :                         state, format("in the modelDescription file ({}).", state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInFMU));
    1785           0 :                     ShowContinueError(state, "Check the input file and the modelDescription file again.");
    1786             :                 }
    1787             :                 // check whether the number of output variables in fmu is less than in the idf
    1788           3 :                 if (state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInFMU <
    1789           3 :                     state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInIDF) {
    1790           0 :                     ShowWarningError(state,
    1791           0 :                                      format("InitExternalInterfaceFMUImport: The number of output variables defined in input file ({})",
    1792           0 :                                             state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInIDF));
    1793           0 :                     ShowContinueError(state,
    1794           0 :                                       format("of instance \"{}\" of FMU \"{}\" is bigger than the number of output variables",
    1795           0 :                                              state.dataExternalInterface->FMU(i).Instance(j).Name,
    1796           0 :                                              state.dataExternalInterface->FMU(i).Name));
    1797           0 :                     ShowContinueError(
    1798           0 :                         state, format("in the modelDescription file ({}).", state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInFMU));
    1799           0 :                     ShowContinueError(state, "Check the input file and the modelDescription file again.");
    1800             :                 }
    1801             : 
    1802           3 :                 DisplayString(state,
    1803           6 :                               format("Number of inputs in instance \"{}\" of FMU \"{}\" = \"{}\".",
    1804           3 :                                      state.dataExternalInterface->FMU(i).Instance(j).Name,
    1805           3 :                                      state.dataExternalInterface->FMU(i).Name,
    1806           3 :                                      state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF));
    1807           3 :                 DisplayString(state,
    1808           6 :                               format("Number of outputs in instance \"{}\" of FMU \"{}\" = \"{}\".",
    1809           3 :                                      state.dataExternalInterface->FMU(i).Instance(j).Name,
    1810           3 :                                      state.dataExternalInterface->FMU(i).Name,
    1811           3 :                                      state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesInIDF));
    1812             :             }
    1813             :         }
    1814           3 :         StopExternalInterfaceIfError(state);
    1815           3 :         state.dataExternalInterface->FirstCallIni = false;
    1816             :     }
    1817      143523 : }
    1818             : 
    1819           3 : std::string trim(std::string const &str)
    1820             : {
    1821           3 :     std::size_t first = str.find_first_not_of(' ');
    1822           3 :     std::size_t last = str.find_last_not_of(' ');
    1823           3 :     return str.substr(first, last - first + 1);
    1824             : }
    1825             : 
    1826           6 : Real64 GetCurSimStartTimeSeconds(const EnergyPlusData &state)
    1827             : {
    1828             :     // FUNCTION INFORMATION:
    1829             :     //       AUTHOR         Thierry S. Nouidui, Michael Wetter, Wangda Zuo
    1830             :     //       DATE WRITTEN   August 2011
    1831             : 
    1832             :     // PURPOSE OF THIS FUNCTION:
    1833             :     //  Get the current month and day in the runperiod and convert
    1834             :     //  it into seconds.
    1835             : 
    1836             :     // Locals
    1837             :     Real64 simtime;
    1838             : 
    1839           6 :     if (!state.dataEnvrn->CurrentYearIsLeapYear) {
    1840           6 :         switch (state.dataEnvrn->Month) {
    1841           6 :         case 1:
    1842           6 :             simtime = 0;
    1843           6 :             break;
    1844           0 :         case 2:
    1845           0 :             simtime = 31;
    1846           0 :             break;
    1847           0 :         case 3:
    1848           0 :             simtime = 59;
    1849           0 :             break;
    1850           0 :         case 4:
    1851           0 :             simtime = 90;
    1852           0 :             break;
    1853           0 :         case 5:
    1854           0 :             simtime = 120;
    1855           0 :             break;
    1856           0 :         case 6:
    1857           0 :             simtime = 151;
    1858           0 :             break;
    1859           0 :         case 7:
    1860           0 :             simtime = 181;
    1861           0 :             break;
    1862           0 :         case 8:
    1863           0 :             simtime = 212;
    1864           0 :             break;
    1865           0 :         case 9:
    1866           0 :             simtime = 243;
    1867           0 :             break;
    1868           0 :         case 10:
    1869           0 :             simtime = 273;
    1870           0 :             break;
    1871           0 :         case 11:
    1872           0 :             simtime = 304;
    1873           0 :             break;
    1874           0 :         case 12:
    1875           0 :             simtime = 334;
    1876           0 :             break;
    1877           0 :         default:
    1878           0 :             simtime = 0;
    1879             :         }
    1880             :     } else {
    1881           0 :         switch (state.dataEnvrn->Month) {
    1882           0 :         case 1:
    1883           0 :             simtime = 0;
    1884           0 :             break;
    1885           0 :         case 2:
    1886           0 :             simtime = 31;
    1887           0 :             break;
    1888           0 :         case 3:
    1889           0 :             simtime = 59 + 1;
    1890           0 :             break;
    1891           0 :         case 4:
    1892           0 :             simtime = 90 + 1;
    1893           0 :             break;
    1894           0 :         case 5:
    1895           0 :             simtime = 120 + 1;
    1896           0 :             break;
    1897           0 :         case 6:
    1898           0 :             simtime = 151 + 1;
    1899           0 :             break;
    1900           0 :         case 7:
    1901           0 :             simtime = 181 + 1;
    1902           0 :             break;
    1903           0 :         case 8:
    1904           0 :             simtime = 212 + 1;
    1905           0 :             break;
    1906           0 :         case 9:
    1907           0 :             simtime = 243 + 1;
    1908           0 :             break;
    1909           0 :         case 10:
    1910           0 :             simtime = 273 + 1;
    1911           0 :             break;
    1912           0 :         case 11:
    1913           0 :             simtime = 304 + 1;
    1914           0 :             break;
    1915           0 :         case 12:
    1916           0 :             simtime = 334 + 1;
    1917           0 :             break;
    1918           0 :         default:
    1919           0 :             simtime = 0;
    1920             :         }
    1921             :     }
    1922             : 
    1923           6 :     simtime = 24 * (simtime + (state.dataEnvrn->DayOfMonth - 1)); // day of month does not need to be stubtracted??
    1924           6 :     simtime = 60 * (simtime + (state.dataGlobal->HourOfDay - 1)); // hours to minutes
    1925           6 :     simtime = 60 * (simtime);                                     // minutes to seconds
    1926             : 
    1927           6 :     return simtime;
    1928             : }
    1929             : 
    1930      143523 : void CalcExternalInterfaceFMUImport(EnergyPlusData &state)
    1931             : {
    1932             : 
    1933             :     // SUBROUTINE INFORMATION:
    1934             :     //       AUTHOR         Thierry S. Nouidui, Michael Wetter, Wangda Zuo
    1935             :     //       DATE WRITTEN   08Aug2011
    1936             : 
    1937             :     // PURPOSE OF THIS SUBROUTINE:
    1938             :     // This subroutine organizes the data exchange between FMU and EnergyPlus.
    1939             : 
    1940             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1941      143523 :     Array1D_string Alphas(5);
    1942      143523 :     Array1D_int keyIndexes(1);     // Array index for
    1943      143523 :     Array1D_string NamesOfKeys(1); // Specific key name
    1944             : 
    1945      146883 :     if (state.dataGlobal->WarmupFlag &&
    1946        3360 :         (state.dataGlobal->KindOfSim != Constant::KindOfSim::RunPeriodWeather)) { // No data exchange during design days
    1947           0 :         if (state.dataExternalInterface->FirstCallDesignDays) {
    1948           0 :             ShowWarningError(state, "ExternalInterface/CalcExternalInterfaceFMUImport: ExternalInterface does not exchange data during design days.");
    1949             :         }
    1950           0 :         state.dataExternalInterface->FirstCallDesignDays = false;
    1951             :     }
    1952      143523 :     if (state.dataGlobal->WarmupFlag && (state.dataGlobal->KindOfSim == Constant::KindOfSim::RunPeriodWeather)) { // Data exchange after design days
    1953        3360 :         if (state.dataExternalInterface->FirstCallWUp) {
    1954             :             // set the report during warmup to true so that variables are also updated during the warmup
    1955           3 :             state.dataSysVars->UpdateDataDuringWarmupExternalInterface = true;
    1956           3 :             state.dataExternalInterface->hStep = (60.0 * state.dataGlobal->TimeStepZone) * 60.0;
    1957           3 :             state.dataExternalInterface->tStart = GetCurSimStartTimeSeconds(state);
    1958           3 :             state.dataExternalInterface->tStop = state.dataExternalInterface->tStart + 24.0 * 3600.0;
    1959           3 :             state.dataExternalInterface->tComm = state.dataExternalInterface->tStart;
    1960             : 
    1961             :             // instantiate and initialize the unpack fmus
    1962           3 :             InstantiateInitializeFMUImport(state);
    1963             : 
    1964             :             // allocate memory for a temporary FMU that will be used at the end of the warmup
    1965           3 :             state.dataExternalInterface->FMUTemp.allocate(state.dataExternalInterface->NumFMUObjects);
    1966           6 :             for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1967           3 :                 state.dataExternalInterface->FMUTemp(i).Instance.allocate(state.dataExternalInterface->FMU(i).NumInstances);
    1968             :             }
    1969           6 :             for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1970           6 :                 for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1971           6 :                     state.dataExternalInterface->FMUTemp(i).Instance(j).fmuInputVariable.allocate(
    1972           3 :                         state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF);
    1973           6 :                     state.dataExternalInterface->FMUTemp(i).Instance(j).eplusOutputVariable.allocate(
    1974           3 :                         state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF);
    1975           6 :                     state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableSchedule.allocate(
    1976           3 :                         state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesSchedule);
    1977           6 :                     state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableVariable.allocate(
    1978           3 :                         state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesVariable);
    1979           6 :                     state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableActuator.allocate(
    1980           3 :                         state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesActuator);
    1981             :                 }
    1982             :             }
    1983             : 
    1984           3 :             GetSetVariablesAndDoStepFMUImport(state);
    1985           3 :             state.dataExternalInterface->tComm += state.dataExternalInterface->hStep;
    1986           3 :             state.dataExternalInterface->FirstCallWUp = false;
    1987             : 
    1988             :         } else {
    1989        3357 :             if (state.dataExternalInterface->tComm < state.dataExternalInterface->tStop) {
    1990        3331 :                 GetSetVariablesAndDoStepFMUImport(state);
    1991             :                 // Advance the communication time step
    1992        3331 :                 state.dataExternalInterface->tComm += state.dataExternalInterface->hStep;
    1993             :             } else {
    1994          52 :                 for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    1995          52 :                     for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    1996             : 
    1997          26 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).NumInputVariablesInIDF =
    1998          26 :                             state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF;
    1999         110 :                         for (int k = 1; k <= state.dataExternalInterface->FMU(i).Instance(j).NumInputVariablesInIDF; ++k) {
    2000          84 :                             state.dataExternalInterface->FMUTemp(i).Instance(j).fmuInputVariable(k).ValueReference =
    2001          84 :                                 state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(k).ValueReference;
    2002          84 :                             state.dataExternalInterface->FMUTemp(i).Instance(j).eplusOutputVariable(k).RTSValue =
    2003          84 :                                 state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).RTSValue;
    2004          84 :                             state.dataExternalInterface->FMUTemp(i).Instance(j).eplusOutputVariable(k).ITSValue =
    2005          84 :                                 state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).ITSValue;
    2006          84 :                             state.dataExternalInterface->FMUTemp(i).Instance(j).eplusOutputVariable(k).VarType =
    2007          84 :                                 state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(k).VarType;
    2008             :                         }
    2009             : 
    2010             :                         // save values that will be set in EnergyPlus (Schedule)
    2011          26 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).NumOutputVariablesSchedule =
    2012          26 :                             state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesSchedule;
    2013          58 :                         for (int k = 1; k <= state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesSchedule; ++k) {
    2014          32 :                             state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableSchedule(k).RealVarValue =
    2015          32 :                                 state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule(k).RealVarValue;
    2016             :                         }
    2017             : 
    2018             :                         // save values that will be set in EnergyPlus (Variable)
    2019          26 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).NumOutputVariablesVariable =
    2020          26 :                             state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesVariable;
    2021          31 :                         for (int k = 1; k <= state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesVariable; ++k) {
    2022           5 :                             state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableVariable(k).RealVarValue =
    2023           5 :                                 state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable(k).RealVarValue;
    2024             :                         }
    2025             : 
    2026             :                         // save values that will be set in EnergyPlus (Actuator)
    2027          26 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).NumOutputVariablesActuator =
    2028          26 :                             state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesActuator;
    2029          31 :                         for (int k = 1; k <= state.dataExternalInterface->FMU(i).Instance(j).NumOutputVariablesActuator; ++k) {
    2030           5 :                             state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableActuator(k).RealVarValue =
    2031           5 :                                 state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator(k).RealVarValue;
    2032             :                         }
    2033             :                     }
    2034             :                 }
    2035             : 
    2036          26 :                 StopExternalInterfaceIfError(state);
    2037             : 
    2038             :                 // Terminate all FMUs
    2039          26 :                 TerminateResetFreeFMUImport(state, state.dataExternalInterface->fmiEndSimulation);
    2040             : 
    2041             :                 // Reset the communication time step
    2042          26 :                 state.dataExternalInterface->tComm = state.dataExternalInterface->tStart;
    2043             : 
    2044             :                 // Reinstantiate and reinitialize the FMUs
    2045          26 :                 InstantiateInitializeFMUImport(state);
    2046             : 
    2047             :                 // Set the values that have been saved in the FMUs-- saveFMUStateVariables ()
    2048          52 :                 for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    2049          52 :                     for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    2050             : 
    2051          26 :                         std::vector<unsigned int> valRefVec;
    2052         110 :                         for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable); ++x) {
    2053          84 :                             valRefVec.push_back(state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable(x).ValueReference);
    2054             :                         }
    2055             : 
    2056          26 :                         std::vector<Real64> rtsValVec;
    2057         110 :                         for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable); ++x) {
    2058          84 :                             rtsValVec.push_back(state.dataExternalInterface->FMU(i).Instance(j).eplusOutputVariable(x).RTSValue);
    2059             :                         }
    2060             : 
    2061             :                         // make the library call
    2062          26 :                         state.dataExternalInterface->FMU(i).Instance(j).fmistatus =
    2063          26 :                             fmiEPlusSetReal(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
    2064          26 :                                             &valRefVec[0],
    2065          26 :                                             &rtsValVec[0],
    2066          26 :                                             &state.dataExternalInterface->FMUTemp(i).Instance(j).NumInputVariablesInIDF,
    2067          26 :                                             &state.dataExternalInterface->FMU(i).Instance(j).Index);
    2068             : 
    2069          26 :                         if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiOK) {
    2070           0 :                             ShowSevereError(
    2071             :                                 state,
    2072           0 :                                 format("ExternalInterface/CalcExternalInterfaceFMUImport: Error when trying to set an input value in instance \"{}\"",
    2073           0 :                                        state.dataExternalInterface->FMU(i).Instance(j).Name));
    2074           0 :                             ShowContinueError(state,
    2075           0 :                                               format("of FMU \"{}\"; Error Code = \"{}\"",
    2076           0 :                                                      state.dataExternalInterface->FMU(i).Name,
    2077           0 :                                                      state.dataExternalInterface->FMU(i).Instance(j).fmistatus));
    2078           0 :                             state.dataExternalInterface->ErrorsFound = true;
    2079           0 :                             StopExternalInterfaceIfError(state);
    2080             :                         }
    2081          26 :                     }
    2082             :                 }
    2083             :                 // set the flag to reinitialize states to be true
    2084          26 :                 state.dataExternalInterface->FlagReIni = true;
    2085          26 :                 GetSetVariablesAndDoStepFMUImport(state);
    2086          26 :                 state.dataExternalInterface->FlagReIni = false;
    2087             :                 // advance one time step ahead for the next calculation
    2088          26 :                 state.dataExternalInterface->tComm += state.dataExternalInterface->hStep;
    2089             :             }
    2090             :         }
    2091             :     }
    2092             :     // BeginSimulation
    2093      143523 :     if (!state.dataGlobal->WarmupFlag && (state.dataGlobal->KindOfSim == Constant::KindOfSim::RunPeriodWeather)) {
    2094             : 
    2095      140163 :         if (state.dataExternalInterface->FirstCallTStep) {
    2096             :             // reset the UpdateDataDuringWarmupExternalInterface to be false.
    2097           3 :             state.dataSysVars->UpdateDataDuringWarmupExternalInterface = false;
    2098             :             // The time is computed in seconds for FMU
    2099           3 :             state.dataExternalInterface->tStart = GetCurSimStartTimeSeconds(state);
    2100           6 :             state.dataExternalInterface->tStop =
    2101           3 :                 state.dataExternalInterface->tStart + (state.dataEnvrn->TotalOverallSimDays - state.dataEnvrn->TotDesDays) * 24.0 * 3600.0;
    2102           3 :             state.dataExternalInterface->tComm = state.dataExternalInterface->tStart;
    2103             : 
    2104             :             // Terminate all FMUs
    2105           3 :             TerminateResetFreeFMUImport(state, state.dataExternalInterface->fmiEndSimulation);
    2106             : 
    2107             :             // Reinstantiate and reinitialize the FMUs
    2108           3 :             InstantiateInitializeFMUImport(state);
    2109             : 
    2110             :             // Set the values that have been saved in the FMUs-- saveFMUStateVariables ()
    2111           6 :             for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    2112           6 :                 for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    2113             : 
    2114             :                     // make vectors first
    2115           3 :                     std::vector<unsigned int> valRefVec;
    2116          11 :                     for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMUTemp(i).Instance(j).fmuInputVariable); ++x) {
    2117           8 :                         valRefVec.push_back(state.dataExternalInterface->FMUTemp(i).Instance(j).fmuInputVariable(x).ValueReference);
    2118             :                     }
    2119           3 :                     std::vector<Real64> rtsValVec;
    2120          11 :                     for (unsigned long x = 1; x <= size(state.dataExternalInterface->FMUTemp(i).Instance(j).eplusOutputVariable); ++x) {
    2121           8 :                         rtsValVec.push_back(state.dataExternalInterface->FMUTemp(i).Instance(j).eplusOutputVariable(x).RTSValue);
    2122             :                     }
    2123             : 
    2124             :                     // make the library call
    2125           3 :                     state.dataExternalInterface->FMU(i).Instance(j).fmistatus =
    2126           3 :                         fmiEPlusSetReal(&state.dataExternalInterface->FMU(i).Instance(j).fmicomponent,
    2127           3 :                                         &valRefVec[0],
    2128           3 :                                         &rtsValVec[0],
    2129           3 :                                         &state.dataExternalInterface->FMUTemp(i).Instance(j).NumInputVariablesInIDF,
    2130           3 :                                         &state.dataExternalInterface->FMU(i).Instance(j).Index);
    2131             : 
    2132           3 :                     if (state.dataExternalInterface->FMU(i).Instance(j).fmistatus != fmiOK) {
    2133           0 :                         ShowSevereError(state, "ExternalInterface/CalcExternalInterfaceFMUImport: ");
    2134           0 :                         ShowContinueError(state, "Error when trying to set inputs in instance");
    2135           0 :                         ShowContinueError(state,
    2136           0 :                                           format("\"{}\" of FMU \"{}\"",
    2137           0 :                                                  state.dataExternalInterface->FMU(i).Instance(j).Name,
    2138           0 :                                                  state.dataExternalInterface->FMU(i).Name));
    2139           0 :                         ShowContinueError(state, format("Error Code = \"{}\"", state.dataExternalInterface->FMU(i).Instance(j).fmistatus));
    2140           0 :                         state.dataExternalInterface->ErrorsFound = true;
    2141           0 :                         StopExternalInterfaceIfError(state);
    2142             :                     }
    2143           3 :                 }
    2144             :             }
    2145             :             // set the flag to reinitialize states to be true
    2146           3 :             state.dataExternalInterface->FlagReIni = true;
    2147           3 :             GetSetVariablesAndDoStepFMUImport(state);
    2148           3 :             state.dataExternalInterface->FlagReIni = false;
    2149             :             // advance one time step ahead for the next calculation
    2150           3 :             state.dataExternalInterface->tComm += state.dataExternalInterface->hStep;
    2151           3 :             state.dataExternalInterface->FirstCallTStep = false;
    2152             :         } else {
    2153      140160 :             if (state.dataExternalInterface->tComm != state.dataExternalInterface->tStop) {
    2154      140157 :                 GetSetVariablesAndDoStepFMUImport(state);
    2155      140157 :                 state.dataExternalInterface->tComm += state.dataExternalInterface->hStep;
    2156             :             } else {
    2157             :                 // Terminate reset and free Slaves
    2158           3 :                 state.dataExternalInterface->fmiEndSimulation = 1;
    2159           3 :                 TerminateResetFreeFMUImport(state, state.dataExternalInterface->fmiEndSimulation);
    2160           6 :                 for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    2161           6 :                     for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    2162             :                         // Deallocate used objects
    2163           3 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).fmuInputVariable.deallocate();
    2164           3 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).eplusOutputVariable.deallocate();
    2165           3 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableSchedule.deallocate();
    2166           3 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableVariable.deallocate();
    2167           3 :                         state.dataExternalInterface->FMUTemp(i).Instance(j).fmuOutputVariableActuator.deallocate();
    2168             :                     }
    2169             :                 }
    2170             : 
    2171           6 :                 for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    2172           3 :                     state.dataExternalInterface->FMUTemp(i).Instance.deallocate();
    2173             :                 }
    2174             : 
    2175           3 :                 state.dataExternalInterface->FMUTemp.deallocate();
    2176             : 
    2177           6 :                 for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    2178           6 :                     for (int j = 1; j <= state.dataExternalInterface->FMU(i).NumInstances; ++j) {
    2179           3 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableSchedule.deallocate();
    2180           3 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableSchedule.deallocate();
    2181           3 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableVariable.deallocate();
    2182           3 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableVariable.deallocate();
    2183           3 :                         state.dataExternalInterface->FMU(i).Instance(j).eplusInputVariableActuator.deallocate();
    2184           3 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuOutputVariableActuator.deallocate();
    2185           3 :                         state.dataExternalInterface->FMU(i).Instance(j).fmuInputVariable.deallocate();
    2186           3 :                         state.dataExternalInterface->FMU(i).Instance(j).checkfmuInputVariable.deallocate();
    2187             :                     }
    2188             :                 }
    2189             : 
    2190           6 :                 for (int i = 1; i <= state.dataExternalInterface->NumFMUObjects; ++i) {
    2191           3 :                     state.dataExternalInterface->FMU(i).Instance.deallocate();
    2192             :                 }
    2193           3 :                 state.dataExternalInterface->FMU.deallocate();
    2194             :             }
    2195             :         }
    2196             :     }
    2197      143523 : }
    2198             : 
    2199           3 : void ValidateRunControl(EnergyPlusData &state)
    2200             : {
    2201             :     // SUBROUTINE INFORMATION:
    2202             :     //       AUTHOR         Michael Wetter
    2203             :     //       DATE WRITTEN   December 2009
    2204             : 
    2205             :     // PURPOSE OF THIS SUBROUTINE:
    2206             :     // This subroutine ensures that the RunControl object is valid.
    2207             : 
    2208             :     // METHODOLOGY EMPLOYED:
    2209             :     // Use GetObjectItem from the Input Processor
    2210             : 
    2211             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2212           3 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
    2213             : 
    2214           3 :     cCurrentModuleObject = "SimulationControl";
    2215           3 :     int const NumRunControl = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    2216           3 :     if (NumRunControl > 0) {
    2217           2 :         int NumAlphas = 0;  // Number of Alphas for each GetObjectItem call
    2218           2 :         int NumNumbers = 0; // Number of Numbers for each GetObjectItem call
    2219           2 :         int IOStatus = 0;   // Used in GetObjectItem
    2220           6 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    2221             :                                                                  cCurrentModuleObject,
    2222             :                                                                  1,
    2223           2 :                                                                  state.dataIPShortCut->cAlphaArgs,
    2224             :                                                                  NumAlphas,
    2225           2 :                                                                  state.dataIPShortCut->rNumericArgs,
    2226             :                                                                  NumNumbers,
    2227             :                                                                  IOStatus,
    2228             :                                                                  _,
    2229             :                                                                  _,
    2230           2 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
    2231           2 :                                                                  state.dataIPShortCut->cNumericFieldNames);
    2232           2 :         if (state.dataIPShortCut->cAlphaArgs(5) == "NO") { // This run does not have a weather file simulation.
    2233           0 :             ShowSevereError(state, "ExternalInterface: Error in idf file, section SimulationControl:");
    2234           0 :             ShowContinueError(state, "When using the ExternalInterface, a run period from the weather file must be specified");
    2235           0 :             ShowContinueError(state, "in the idf file, because the ExternalInterface interface is not active during");
    2236           0 :             ShowContinueError(state, "warm-up and during sizing.");
    2237           0 :             state.dataExternalInterface->ErrorsFound = true;
    2238             :         }
    2239             :     }
    2240           3 : }
    2241             : 
    2242           0 : void CalcExternalInterface(EnergyPlusData &state)
    2243             : {
    2244             :     // SUBROUTINE INFORMATION:
    2245             :     //       AUTHOR         Michael Wetter
    2246             :     //       DATE WRITTEN   2Dec2007
    2247             : 
    2248             :     // SUBROUTINE PARAMETER DEFINITIONS:
    2249           0 :     int constexpr nDblMax(1024); // Maximum number of doubles
    2250             : 
    2251             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2252             :     Real64 curSimTim; // current simulation time
    2253             :     Real64 preSimTim; // previous time step's simulation time
    2254             : 
    2255           0 :     Array1D<Real64> dblValWri(nDblMax);
    2256           0 :     Array1D<Real64> dblValRea(nDblMax);
    2257             : 
    2258           0 :     if (state.dataExternalInterface->firstCall) {
    2259           0 :         DisplayString(state, "ExternalInterface starts first data exchange.");
    2260           0 :         state.dataExternalInterface->simulationStatus = 2;
    2261           0 :         preSimTim = 0; // In the first call, E+ did not reset SimTimeSteps to zero
    2262             :     } else {
    2263           0 :         preSimTim = state.dataGlobal->SimTimeSteps * state.dataGlobal->MinutesPerTimeStep * 60.0;
    2264             :     }
    2265             : 
    2266             :     // Socket asked to terminate simulation, but simulation continues
    2267           0 :     if (state.dataExternalInterface->noMoreValues && state.dataExternalInterface->showContinuationWithoutUpdate) {
    2268           0 :         if (state.dataExternalInterface->haveExternalInterfaceBCVTB) {
    2269           0 :             ShowWarningError(
    2270           0 :                 state, format("ExternalInterface: Continue simulation without updated values from server at t ={:.2T} hours", preSimTim / 3600.0));
    2271             :         }
    2272           0 :         state.dataExternalInterface->showContinuationWithoutUpdate = false;
    2273             :     }
    2274             : 
    2275             :     // Usual branch, control is configured and simulation should continue
    2276           0 :     if (state.dataExternalInterface->configuredControlPoints && (!state.dataExternalInterface->noMoreValues)) {
    2277             :         // Data to be exchanged
    2278           0 :         int nDblWri = size(state.dataExternalInterface->varTypes); // number of doubles to write to socket
    2279           0 :         int nDblRea = 0;                                           // number of doubles to read from socket
    2280           0 :         int flaWri = 0;                                            // flag to write to the socket
    2281             : 
    2282             :         // Get EnergyPlus variables
    2283           0 :         if (state.dataExternalInterface->firstCall) { // bug fix causing external interface to send zero at the beginning of sim, Thierry Nouidui
    2284           0 :             for (int i = 1; i <= nDblWri; ++i) {
    2285           0 :                 dblValWri(i) =
    2286           0 :                     GetInternalVariableValue(state, state.dataExternalInterface->varTypes(i), state.dataExternalInterface->keyVarIndexes(i));
    2287             :             }
    2288             :         } else {
    2289           0 :             for (int i = 1; i <= nDblWri; ++i) {
    2290           0 :                 dblValWri(i) = GetInternalVariableValueExternalInterface(
    2291           0 :                     state, state.dataExternalInterface->varTypes(i), state.dataExternalInterface->keyVarIndexes(i));
    2292             :             }
    2293             :         }
    2294             : 
    2295             :         // Exchange data with socket
    2296           0 :         int retVal = 0;
    2297           0 :         int flaRea = 0; // flag read from the socket
    2298           0 :         if (state.dataExternalInterface->haveExternalInterfaceBCVTB) {
    2299           0 :             retVal = exchangedoubleswithsocket(&state.dataExternalInterface->socketFD,
    2300             :                                                &flaWri,
    2301             :                                                &flaRea,
    2302             :                                                &nDblWri,
    2303             :                                                &nDblRea,
    2304             :                                                &preSimTim,
    2305             :                                                dblValWri.data(),
    2306             :                                                &curSimTim,
    2307             :                                                dblValRea.data());
    2308           0 :         } else if (state.dataExternalInterface->haveExternalInterfaceFMUExport) {
    2309           0 :             retVal = exchangedoubleswithsocketFMU(&state.dataExternalInterface->socketFD,
    2310             :                                                   &flaWri,
    2311             :                                                   &flaRea,
    2312             :                                                   &nDblWri,
    2313             :                                                   &nDblRea,
    2314             :                                                   &preSimTim,
    2315             :                                                   dblValWri.data(),
    2316             :                                                   &curSimTim,
    2317             :                                                   dblValRea.data(),
    2318           0 :                                                   &state.dataExternalInterface->FMUExportActivate);
    2319             :         }
    2320           0 :         bool continueSimulation = true;
    2321             : 
    2322             :         // Check for errors, in which case we terminate the simulation loop
    2323             :         // Added a check since the FMUExport is terminated with the flaRea set to 1.
    2324           0 :         if (state.dataExternalInterface->haveExternalInterfaceBCVTB ||
    2325           0 :             (state.dataExternalInterface->haveExternalInterfaceFMUExport && (flaRea == 0))) {
    2326           0 :             if (retVal != 0) {
    2327           0 :                 continueSimulation = false;
    2328           0 :                 ShowSevereError(state,
    2329           0 :                                 format("ExternalInterface: Socket communication received error value \"{:2}\" at time = {:.2T} hours.",
    2330             :                                        retVal,
    2331           0 :                                        preSimTim / 3600));
    2332           0 :                 ShowContinueError(state, format("ExternalInterface: Flag from server \"{:2}\".", flaRea));
    2333           0 :                 state.dataExternalInterface->ErrorsFound = true;
    2334           0 :                 StopExternalInterfaceIfError(state);
    2335             :             }
    2336             :         }
    2337             : 
    2338             :         // Check communication flag
    2339           0 :         if (flaRea != 0) {
    2340             :             // No more values will be received in future steps
    2341             :             // Added a check since the FMUExport  is terminated with the flaRea set to 1.
    2342           0 :             state.dataExternalInterface->noMoreValues = true;
    2343           0 :             if (state.dataExternalInterface->haveExternalInterfaceBCVTB) {
    2344           0 :                 ShowSevereError(state, format("ExternalInterface: Received end of simulation flag at time = {:.2T} hours.", preSimTim / 3600));
    2345           0 :                 StopExternalInterfaceIfError(state);
    2346             :             }
    2347             :         }
    2348             : 
    2349             :         // Make sure we get the right number of double values, unless retVal != 0
    2350           0 :         if ((flaRea == 0) && (!state.dataExternalInterface->ErrorsFound) && continueSimulation &&
    2351           0 :             (nDblRea != isize(state.dataExternalInterface->varInd))) {
    2352           0 :             ShowSevereError(
    2353             :                 state,
    2354           0 :                 format("ExternalInterface: Received \"{}\" double values, expected \"{}\".", nDblRea, size(state.dataExternalInterface->varInd)));
    2355           0 :             state.dataExternalInterface->ErrorsFound = true;
    2356           0 :             StopExternalInterfaceIfError(state);
    2357             :         }
    2358             : 
    2359             :         // No errors found. Assign exchanged variables
    2360           0 :         if ((flaRea == 0) && continueSimulation) {
    2361           0 :             for (int i = 1; i <= isize(state.dataExternalInterface->varInd); ++i) {
    2362           0 :                 if (state.dataExternalInterface->inpVarTypes(i) == indexSchedule) {
    2363           0 :                     ScheduleManager::ExternalInterfaceSetSchedule(state, state.dataExternalInterface->varInd(i), dblValRea(i));
    2364           0 :                 } else if ((state.dataExternalInterface->inpVarTypes(i) == indexVariable) ||
    2365           0 :                            (state.dataExternalInterface->inpVarTypes(i) == indexActuator)) {
    2366           0 :                     RuntimeLanguageProcessor::ExternalInterfaceSetErlVariable(state, state.dataExternalInterface->varInd(i), dblValRea(i));
    2367             :                 } else {
    2368           0 :                     ShowContinueError(state, "ExternalInterface: Error in finding the type of the input variable for EnergyPlus");
    2369           0 :                     ShowContinueError(state, format("variable index: {}. Variable will not be updated.", i));
    2370             :                 }
    2371             :             }
    2372             :         }
    2373             :     }
    2374             : 
    2375             :     // If we have Erl variables, we need to call ManageEMS so that they get updated in the Erl data structure
    2376           0 :     if (state.dataExternalInterface->useEMS) {
    2377             :         bool anyRan;
    2378           0 :         EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::ExternalInterface, anyRan, ObjexxFCL::Optional_int_const());
    2379             :     }
    2380             : 
    2381           0 :     state.dataExternalInterface->firstCall = false; // bug fix causing external interface to send zero at the beginning of sim, Thierry Nouidui
    2382           0 : }
    2383             : 
    2384           8 : void GetReportVariableKey(
    2385             :     EnergyPlusData &state,
    2386             :     const Array1D_string &varKeys,                   // Standard variable name
    2387             :     int const numberOfKeys,                          // Number of keys=size(state.dataExternalInterface->varKeys)
    2388             :     const Array1D_string &VarNames,                  // Standard variable name
    2389             :     Array1D_int &keyVarIndexes,                      // Array index
    2390             :     Array1D<OutputProcessor::VariableType> &varTypes // Types of variables in state.dataExternalInterface->keystate.dataExternalInterface->varIndexes
    2391             : )
    2392             : {
    2393             :     // SUBROUTINE INFORMATION:
    2394             :     //       AUTHOR         Michael Wetter
    2395             :     //       DATE WRITTEN   2Dec2007
    2396             : 
    2397             :     // PURPOSE OF THIS SUBROUTINE:
    2398             :     // Gets the sensor key index and type for the specified variable key and name
    2399             : 
    2400             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2401           8 :     OutputProcessor::VariableType varType(OutputProcessor::VariableType::Invalid);  // 0=not found, 1=integer, 2=real, 3=meter
    2402           8 :     int numKeys(0);                                                                 // Number of keys found
    2403           8 :     OutputProcessor::StoreType varAvgSum(OutputProcessor::StoreType::Average);      // Variable  is Averaged=1 or Summed=2
    2404           8 :     OutputProcessor::TimeStepType varStepType(OutputProcessor::TimeStepType::Zone); // Variable time step is Zone=1 or HVAC=2
    2405           8 :     Constant::Units varUnits(Constant::Units::None);                                // Units sting, may be blank
    2406           8 :     Array1D_string keyNames;
    2407           8 :     Array1D_int keyIndexes; // Array index for
    2408             :     int Loop, iKey;         // Loop counters
    2409             : 
    2410             :     // Get pointers for variables to be sent to Ptolemy
    2411          16 :     for (Loop = 1; Loop <= numberOfKeys; ++Loop) {
    2412           8 :         GetVariableKeyCountandType(state, VarNames(Loop), numKeys, varType, varAvgSum, varStepType, varUnits);
    2413           8 :         if (varType != OutputProcessor::VariableType::Invalid) {
    2414           8 :             keyIndexes.allocate(numKeys);
    2415           8 :             keyNames.allocate(numKeys);
    2416           8 :             GetVariableKeys(state, VarNames(Loop), varType, keyNames, keyIndexes);
    2417             :             // Find key index whose keyName is equal to keyNames(Loop)
    2418           8 :             int max(keyIndexes.size());
    2419           8 :             for (iKey = 1; iKey <= max; ++iKey) {
    2420           8 :                 if (keyNames(iKey) == varKeys(Loop)) {
    2421           8 :                     keyVarIndexes(Loop) = keyIndexes(iKey);
    2422           8 :                     varTypes(Loop) = varType;
    2423           8 :                     break;
    2424             :                 }
    2425             :             }
    2426           8 :             keyIndexes.deallocate();
    2427           8 :             keyNames.deallocate();
    2428             :         }
    2429           8 :         if ((varType == OutputProcessor::VariableType::Invalid) || (iKey > numKeys)) {
    2430           0 :             ShowSevereError(state,
    2431           0 :                             format("ExternalInterface: Simulation model has no variable \"{}\" with key \"{}\".", VarNames(Loop), varKeys(Loop)));
    2432           0 :             state.dataExternalInterface->ErrorsFound = true;
    2433             :         }
    2434             :     }
    2435           8 : }
    2436             : 
    2437        7146 : void WarnIfExternalInterfaceObjectsAreUsed(EnergyPlusData &state, std::string const &ObjectWord)
    2438             : {
    2439             :     // SUBROUTINE INFORMATION:
    2440             :     //       AUTHOR         Michael Wetter
    2441             :     //       DATE WRITTEN   December 2009
    2442             : 
    2443             :     // PURPOSE OF THIS SUBROUTINE:
    2444             :     // This subroutine writes a warning if ExternalInterface objects are used in the
    2445             :     // idf file, but the ExternalInterface link is not specified.
    2446             : 
    2447        7146 :     int const NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ObjectWord);
    2448        7146 :     if (NumObjects > 0) {
    2449           0 :         ShowWarningError(state, format("IDF file contains object \"{}\",", ObjectWord));
    2450           0 :         ShowContinueError(state, "but object \"ExternalInterface\" with appropriate key entry is not specified. Values will not be updated.");
    2451             :     }
    2452        7146 : }
    2453             : 
    2454           3 : void VerifyExternalInterfaceObject(EnergyPlusData &state)
    2455             : {
    2456             :     // SUBROUTINE INFORMATION:
    2457             :     //       AUTHOR         Michael Wetter
    2458             :     //       DATE WRITTEN   12Dec2009
    2459             : 
    2460             :     // PURPOSE OF THIS SUBROUTINE:
    2461             :     // This subroutine verifies the correctness of the fields of
    2462             :     // the ExternalInterface object in the idf file
    2463             : 
    2464             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2465           3 :     int NumAlphas(0);  // Number of Alphas for each GetObjectItem call
    2466           3 :     int NumNumbers(0); // Number of Numbers for each GetObjectItem call
    2467           3 :     int IOStatus(0);   // Used in GetObjectItem
    2468           3 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
    2469             : 
    2470           3 :     cCurrentModuleObject = "ExternalInterface";
    2471           9 :     state.dataInputProcessing->inputProcessor->getObjectItem(state,
    2472             :                                                              cCurrentModuleObject,
    2473             :                                                              1,
    2474           3 :                                                              state.dataIPShortCut->cAlphaArgs,
    2475             :                                                              NumAlphas,
    2476           3 :                                                              state.dataIPShortCut->rNumericArgs,
    2477             :                                                              NumNumbers,
    2478             :                                                              IOStatus,
    2479             :                                                              _,
    2480             :                                                              _,
    2481           3 :                                                              state.dataIPShortCut->cAlphaFieldNames,
    2482           3 :                                                              state.dataIPShortCut->cNumericFieldNames);
    2483           3 :     if ((!Util::SameString(state.dataIPShortCut->cAlphaArgs(1), "PtolemyServer")) &&
    2484           3 :         (!Util::SameString(state.dataIPShortCut->cAlphaArgs(1), "FunctionalMockupUnitImport")) &&
    2485           3 :         (!Util::SameString(state.dataIPShortCut->cAlphaArgs(1), "FunctionalMockupUnitExport"))) {
    2486           0 :         ShowSevereError(state,
    2487           0 :                         format("VerifyExternalInterfaceObject: {}, invalid {}=\"{}\".",
    2488             :                                cCurrentModuleObject,
    2489           0 :                                state.dataIPShortCut->cAlphaFieldNames(1),
    2490           0 :                                state.dataIPShortCut->cAlphaArgs(1)));
    2491           0 :         ShowContinueError(state, "only \"PtolemyServer or FunctionalMockupUnitImport or FunctionalMockupUnitExport\" allowed.");
    2492           0 :         state.dataExternalInterface->ErrorsFound = true;
    2493             :     }
    2494           3 : }
    2495             : 
    2496          33 : std::vector<char> getCharArrayFromString(std::string const &originalString)
    2497             : {
    2498             :     // c_str returns null terminated, so we don't need a +1?
    2499          33 :     return std::vector<char>(originalString.c_str(), originalString.c_str() + originalString.size());
    2500             : }
    2501             : 
    2502          16 : std::string getStringFromCharArray(std::vector<char> originalCharArray)
    2503             : {
    2504          16 :     originalCharArray.push_back('\0');
    2505          16 :     return std::string(&originalCharArray.front());
    2506             : }
    2507             : 
    2508             : } // namespace EnergyPlus::ExternalInterface

Generated by: LCOV version 1.14