LCOV - code coverage report
Current view: top level - EnergyPlus - ExternalInterface.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 466 1395 33.4 %
Date: 2023-01-17 19:17:23 Functions: 14 23 60.9 %

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

Generated by: LCOV version 1.13