LCOV - code coverage report
Current view: top level - EnergyPlus - OutputProcessor.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 3250 3914 83.0 %
Date: 2023-01-17 19:17:23 Functions: 81 84 96.4 %

          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             : // C++ Headers
      49             : #include <algorithm>
      50             : #include <cassert>
      51             : #include <cmath>
      52             : #include <cstdio>
      53             : #include <cstring>
      54             : #include <memory>
      55             : #include <string>
      56             : #include <unordered_set>
      57             : 
      58             : // ObjexxFCL Headers
      59             : #include <ObjexxFCL/Array.functions.hh>
      60             : #include <ObjexxFCL/Fmath.hh>
      61             : #include <ObjexxFCL/string.functions.hh>
      62             : 
      63             : // EnergyPlus Headers
      64             : #include "re2/re2.h"
      65             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      66             : #include <EnergyPlus/DataEnvironment.hh>
      67             : #include <EnergyPlus/DataGlobalConstants.hh>
      68             : #include <EnergyPlus/DataIPShortCuts.hh>
      69             : #include <EnergyPlus/DataOutputs.hh>
      70             : #include <EnergyPlus/DataStringGlobals.hh>
      71             : #include <EnergyPlus/DataSystemVariables.hh>
      72             : #include <EnergyPlus/General.hh>
      73             : #include <EnergyPlus/GlobalNames.hh>
      74             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      75             : #include <EnergyPlus/OutputProcessor.hh>
      76             : #include <EnergyPlus/OutputReportPredefined.hh>
      77             : #include <EnergyPlus/ResultsFramework.hh>
      78             : #include <EnergyPlus/SQLiteProcedures.hh>
      79             : #include <EnergyPlus/ScheduleManager.hh>
      80             : #include <EnergyPlus/SortAndStringUtilities.hh>
      81             : #include <EnergyPlus/UtilityRoutines.hh>
      82             : 
      83             : #include <fmt/ostream.h>
      84             : #include <milo/dtoa.h>
      85             : #include <milo/itoa.h>
      86             : 
      87             : namespace EnergyPlus {
      88             : 
      89             : namespace OutputProcessor {
      90             : 
      91             :     // MODULE INFORMATION:
      92             :     //       AUTHOR         Linda Lawrie
      93             :     //       DATE WRITTEN   December 1998
      94             :     //       MODIFIED       na
      95             :     //       RE-ENGINEERED  na
      96             : 
      97             :     // PURPOSE OF THIS MODULE:
      98             :     // This module contains the major Output Processor routines.
      99             :     // In addition, in this file are several routines which can be called
     100             :     // without using the OutputProcessor Module
     101             : 
     102             :     // METHODOLOGY EMPLOYED:
     103             :     // Lots of pointers and other fancy data stuff.
     104             : 
     105             :     // Routines tagged on the end of this module:
     106             :     //  AddToOutputVariableList
     107             :     //  AssignReportNumber
     108             :     //  GenOutputVariablesAuditReport
     109             :     //  GetCurrentMeterValue
     110             :     //  GetInstantMeterValue
     111             :     //  GetInternalVariableValue
     112             :     //  GetInternalVariableValueExternalInterface
     113             :     //  GetMeteredVariables
     114             :     //  GetMeterIndex
     115             :     //  GetMeterResourceType
     116             :     //  GetNumMeteredVariables
     117             :     //  GetVariableKeyCountandType
     118             :     //  GetVariableKeys
     119             :     //  InitPollutionMeterReporting
     120             :     //  ProduceRDDMDD
     121             :     //  ReportingThisVariable
     122             :     //  SetInitialMeterReportingAndOutputNames
     123             :     //  SetupOutputVariable
     124             :     //  UpdateDataandReport
     125             :     //  UpdateMeterReporting
     126             : 
     127             :     // Functions
     128             : 
     129          59 :     inline void ReallocateRVar(EnergyPlusData &state)
     130             :     {
     131          59 :         state.dataOutputProcessor->RVariableTypes.redimension(state.dataOutputProcessor->MaxRVariable += RVarAllocInc);
     132          59 :     }
     133             : 
     134         302 :     inline void ReallocateIVar(EnergyPlusData &state)
     135             :     {
     136         302 :         state.dataOutputProcessor->IVariableTypes.redimension(state.dataOutputProcessor->MaxIVariable += IVarAllocInc);
     137         302 :     }
     138             : 
     139         771 :     void InitializeOutput(EnergyPlusData &state)
     140             :     {
     141             : 
     142             :         // SUBROUTINE INFORMATION:
     143             :         //       AUTHOR         Linda K. Lawrie
     144             :         //       DATE WRITTEN   December 1998
     145             :         //       MODIFIED       na
     146             :         //       RE-ENGINEERED  na
     147             : 
     148             :         // PURPOSE OF THIS SUBROUTINE:
     149             :         // This subroutine initializes the OutputProcessor data structures.
     150             : 
     151             :         // METHODOLOGY EMPLOYED:
     152             :         // na
     153             : 
     154             :         // REFERENCES:
     155             :         // na
     156             : 
     157             :         // USE STATEMENTS:
     158             :         // na
     159             : 
     160             :         // SUBROUTINE ARGUMENT DEFINITIONS:
     161             :         // na
     162             : 
     163             :         // SUBROUTINE PARAMETER DEFINITIONS:
     164             :         // na
     165             : 
     166             :         // INTERFACE BLOCK SPECIFICATIONS:
     167             :         // na
     168             : 
     169             :         // DERIVED TYPE DEFINITIONS:
     170             :         // na
     171             : 
     172             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     173             : 
     174         771 :         auto &op(state.dataOutputProcessor);
     175             : 
     176         771 :         op->RVariableTypes.allocate(RVarAllocInc);
     177         771 :         op->MaxRVariable = RVarAllocInc;
     178             : 
     179         771 :         op->IVariableTypes.allocate(IVarAllocInc);
     180         771 :         op->MaxIVariable = IVarAllocInc;
     181             : 
     182             :         // First index is the frequency designation (-1 = each call, etc)
     183             :         // Second index is the variable type (1=Average, 2=Sum)
     184             :         // Note, Meters always report like Average (with min/max, etc) for hourly and above
     185             :         // FreqNotice( 1, -1 ) = " !Each Call";
     186             :         // FreqNotice( 1, 0 ) = " !TimeStep";
     187             :         // FreqNotice( 1, 1 ) = " !Hourly";
     188             :         // FreqNotice( 1, 2 ) = " !Daily [Value,Min,Hour,Minute,Max,Hour,Minute]";
     189             :         // FreqNotice( 1, 3 ) = " !Monthly [Value,Min,Day,Hour,Minute,Max,Day,Hour,Minute]";
     190             :         // FreqNotice( 1, 4 ) = " !RunPeriod [Value,Min,Month,Day,Hour,Minute,Max,Month,Day,Hour,Minute]";
     191             :         // FreqNotice( 2, -1 ) = " !Each Call";
     192             :         // FreqNotice( 2, 0 ) = " !TimeStep";
     193             :         // FreqNotice( 2, 1 ) = " !Hourly";
     194             :         // FreqNotice( 2, 2 ) = " !Daily [Value,Min,Hour,Minute,Max,Hour,Minute]";
     195             :         // FreqNotice( 2, 3 ) = " !Monthly [Value,Min,Day,Hour,Minute,Max,Day,Hour,Minute]";
     196             :         // FreqNotice( 2, 4 ) = " !RunPeriod [Value,Min,Month,Day,Hour,Minute,Max,Month,Day,Hour,Minute]";
     197             : 
     198         771 :         op->ReportList.allocate(500);
     199         771 :         op->NumReportList = 500;
     200         771 :         op->ReportList = 0;
     201         771 :         op->NumExtraVars = 0;
     202             : 
     203             :         // Initialize end use category names - the indices must match up with endUseNames in OutputReportTabular
     204         771 :         op->EndUseCategory.allocate(state.dataGlobalConst->iEndUse.size());
     205         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Heating)).Name = "Heating";
     206         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Cooling)).Name = "Cooling";
     207         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::InteriorLights)).Name = "InteriorLights";
     208         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::ExteriorLights)).Name = "ExteriorLights";
     209         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::InteriorEquipment)).Name = "InteriorEquipment";
     210         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::ExteriorEquipment)).Name = "ExteriorEquipment";
     211         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Fans)).Name = "Fans";
     212         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Pumps)).Name = "Pumps";
     213         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::HeatRejection)).Name = "HeatRejection";
     214         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Humidification)).Name = "Humidifier";
     215         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::HeatRecovery)).Name = "HeatRecovery";
     216         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::WaterSystem)).Name = "WaterSystems";
     217         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Refrigeration)).Name = "Refrigeration";
     218         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Cogeneration)).Name = "Cogeneration";
     219             : 
     220             :         // Initialize display names for output table - this could go away if end use key names are changed to match
     221         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Heating)).DisplayName = "Heating";
     222         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Cooling)).DisplayName = "Cooling";
     223         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::InteriorLights)).DisplayName = "Interior Lighting";
     224         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::ExteriorLights)).DisplayName = "Exterior Lighting";
     225         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::InteriorEquipment)).DisplayName = "Interior Equipment";
     226         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::ExteriorEquipment)).DisplayName = "Exterior Equipment";
     227         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Fans)).DisplayName = "Fans";
     228         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Pumps)).DisplayName = "Pumps";
     229         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::HeatRejection)).DisplayName = "Heat Rejection";
     230         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Humidification)).DisplayName = "Humidification";
     231         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::HeatRecovery)).DisplayName = "Heat Recovery";
     232         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::WaterSystem)).DisplayName = "Water Systems";
     233         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Refrigeration)).DisplayName = "Refrigeration";
     234         771 :         op->EndUseCategory(state.dataGlobalConst->iEndUse.at(DataGlobalConstants::EndUse::Cogeneration)).DisplayName = "Generators";
     235             : 
     236         771 :         op->OutputInitialized = true;
     237             : 
     238         771 :         op->TimeStepZoneSec = double(state.dataGlobal->MinutesPerTimeStep) * 60.0;
     239             : 
     240         771 :         InitializeMeters(state);
     241         771 :     }
     242             : 
     243        1542 :     void SetupTimePointers(EnergyPlusData &state,
     244             :                            OutputProcessor::SOVTimeStepType const TimeStepTypeKey, // Which timestep is being set up, 'Zone'=1, 'HVAC'=2
     245             :                            Real64 &TimeStep                                        // The timestep variable.  Used to get the address
     246             :     )
     247             :     {
     248             : 
     249             :         // SUBROUTINE INFORMATION:
     250             :         //       AUTHOR         Linda K. Lawrie
     251             :         //       DATE WRITTEN   December 1998
     252             :         //       MODIFIED       na
     253             :         //       RE-ENGINEERED  na
     254             : 
     255             :         // PURPOSE OF THIS SUBROUTINE:
     256             :         // This subroutine sets up the derived type for the output processor that
     257             :         // contains pointers to the TimeStep values used in the simulation.
     258             : 
     259             :         // METHODOLOGY EMPLOYED:
     260             :         // Indicate that the TimeStep passed in is a target for the pointer
     261             :         // attributes in the derived types.
     262             : 
     263             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     264             :         // ValidateTimeStepType will throw a Fatal if not valid
     265        1542 :         TimeStepType timeStepType = ValidateTimeStepType(state, TimeStepTypeKey);
     266             : 
     267        1542 :         TimeSteps tPtr;
     268        1542 :         tPtr.TimeStep = &TimeStep;
     269        1542 :         if (!state.dataOutputProcessor->TimeValue.insert(std::make_pair(timeStepType, tPtr)).second) {
     270             :             // The element was already present... shouldn't happen
     271           0 :             ShowFatalError(state, format("SetupTimePointers was already called for {}", sovTimeStepTypeStrings[(int)TimeStepTypeKey]));
     272             :         }
     273        1542 :     }
     274             : 
     275     6082900 :     void CheckReportVariable(EnergyPlusData &state, std::string_view const KeyedValue, std::string_view const VarName)
     276             :     {
     277             : 
     278             :         // SUBROUTINE INFORMATION:
     279             :         //       AUTHOR         Linda K. Lawrie
     280             :         //       DATE WRITTEN   December 1998
     281             :         //       MODIFIED       na
     282             :         //       RE-ENGINEERED  na
     283             : 
     284             :         // PURPOSE OF THIS SUBROUTINE:
     285             :         // This subroutine will get the report variable information from input and
     286             :         // determine if this variable (KeyedValue and VariableName) should be reported
     287             :         // and, if so, what frequency to report.
     288             : 
     289             :         // This routine is called when SetupOutputVariable is called with no "optional"
     290             :         // Reporting Frequency.  It is expected that SetupOutputVariable would only be
     291             :         // called once for each keyed variable to be triggered for output (from the input
     292             :         // requests).  The optional report frequency would only be used for debugging
     293             :         // purposes.  Therefore, this routine will collect all occasions where this
     294             :         // passed variablename would be reported from the requested input.  It builds
     295             :         // a list of these requests (ReportList) so that the calling routine can propagate
     296             :         // the requests into the correct data structure.
     297             : 
     298             :         // METHODOLOGY EMPLOYED:
     299             :         // This instance being requested will always have a key associated with it.  Matching
     300             :         // instances (from input) may or may not have keys, but only one instance of a reporting
     301             :         // frequency per variable is allowed.  ReportList will be populated with ReqRepVars indices
     302             :         // of those extra things from input that satisfy this condition.
     303             : 
     304             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     305             : 
     306             :         // Make sure that input has been read
     307     6082900 :         GetReportVariableInput(state);
     308             : 
     309     6082900 :         auto &op(state.dataOutputProcessor);
     310             : 
     311             :         // Zero out the array / counter we use to determine if there are duplicates
     312     6082900 :         op->NumExtraVars = 0;
     313     6082900 :         op->ReportList = 0;
     314             : 
     315   177729968 :         for (int i = 1; i <= op->NumOfReqVariables; ++i) {
     316   171647068 :             auto &reqRepVar = op->ReqRepVars(i);
     317             : 
     318   171647068 :             if (!UtilityRoutines::SameString(reqRepVar.VarName, VarName)) {
     319   170928873 :                 continue;
     320             :             }
     321             : 
     322     2753480 :             if (!reqRepVar.Key.empty() && !(reqRepVar.is_simple_string && UtilityRoutines::SameString(reqRepVar.Key, KeyedValue)) &&
     323     1376740 :                 !(!reqRepVar.is_simple_string && RE2::FullMatch(std::string{KeyedValue}, *(reqRepVar.case_insensitive_pattern)))) {
     324      658545 :                 continue;
     325             :             }
     326             : 
     327             :             // A match. Make sure doesn't duplicate
     328       59650 :             reqRepVar.Used = true;
     329       59650 :             bool Dup = false;
     330             :             // op->ReportList is allocated to a large value, so we can't use a std::find_if on it
     331       61897 :             for (int Loop1 = 1; Loop1 <= op->NumExtraVars; ++Loop1) {
     332        4728 :                 if (op->ReqRepVars(op->ReportList(Loop1)).frequency == reqRepVar.frequency &&
     333        1275 :                     op->ReqRepVars(op->ReportList(Loop1)).SchedPtr == reqRepVar.SchedPtr) {
     334        1206 :                     Dup = true;
     335        1206 :                     break;
     336             :                 }
     337             :             }
     338             : 
     339       59650 :             if (!Dup) {
     340       58444 :                 ++op->NumExtraVars;
     341       58444 :                 if (op->NumExtraVars == op->NumReportList) {
     342           0 :                     op->ReportList.redimension(op->NumReportList += 100, 0);
     343             :                 }
     344       58444 :                 op->ReportList(op->NumExtraVars) = i;
     345             :             }
     346             :         }
     347     6082900 :     }
     348             : 
     349       66262 :     static std::string frequencyNotice([[maybe_unused]] StoreType storeType, ReportingFrequency reportingInterval)
     350             :     {
     351       66262 :         switch (reportingInterval) {
     352        1414 :         case ReportingFrequency::EachCall:
     353        1414 :             return " !Each Call";
     354             :             break;
     355       20655 :         case ReportingFrequency::TimeStep:
     356       20655 :             return " !TimeStep";
     357             :             break;
     358       29126 :         case ReportingFrequency::Hourly:
     359       29126 :             return " !Hourly";
     360             :             break;
     361        4833 :         case ReportingFrequency::Daily:
     362        4833 :             return " !Daily [Value,Min,Hour,Minute,Max,Hour,Minute]";
     363             :             break;
     364        5689 :         case ReportingFrequency::Monthly:
     365        5689 :             return " !Monthly [Value,Min,Day,Hour,Minute,Max,Day,Hour,Minute]";
     366             :             break;
     367        1445 :         case ReportingFrequency::Yearly:
     368        1445 :             return " !Annual [Value,Min,Month,Day,Hour,Minute,Max,Month,Day,Hour,Minute]";
     369             :             break;
     370        3100 :         case ReportingFrequency::Simulation:
     371        3100 :             return " !RunPeriod [Value,Min,Month,Day,Hour,Minute,Max,Month,Day,Hour,Minute]";
     372             :             break;
     373           0 :         default:
     374           0 :             return " !Hourly";
     375             :         }
     376             :     }
     377             : 
     378       66262 :     std::string reportingFrequency(ReportingFrequency reportingInterval)
     379             :     {
     380       66262 :         switch (reportingInterval) {
     381        1414 :         case ReportingFrequency::EachCall:
     382        1414 :             return "Each Call";
     383             :             break;
     384       20655 :         case ReportingFrequency::TimeStep:
     385       20655 :             return "TimeStep";
     386             :             break;
     387       29126 :         case ReportingFrequency::Hourly:
     388       29126 :             return "Hourly";
     389             :             break;
     390        4833 :         case ReportingFrequency::Daily:
     391        4833 :             return "Daily";
     392             :             break;
     393        5689 :         case ReportingFrequency::Monthly:
     394        5689 :             return "Monthly";
     395             :             break;
     396        1445 :         case ReportingFrequency::Yearly:
     397        1445 :             return "Annual";
     398             :             break;
     399        3100 :         case ReportingFrequency::Simulation:
     400        3100 :             return "RunPeriod";
     401             :             break;
     402           0 :         default:
     403           0 :             return "Hourly";
     404             :         }
     405             :     }
     406             : 
     407       26991 :     ReportingFrequency determineFrequency(EnergyPlusData &state, const std::string &FreqString)
     408             :     {
     409             : 
     410             :         // SUBROUTINE INFORMATION:
     411             :         //       AUTHOR         Linda K. Lawrie
     412             :         //       DATE WRITTEN   December 1998
     413             :         //       MODIFIED       December 2017; Jason DeGraw
     414             :         //       RE-ENGINEERED  na
     415             : 
     416             :         // PURPOSE OF THIS SUBROUTINE:
     417             :         // This subroutine looks at the passed in report frequency string and
     418             :         // determines the reporting frequency.
     419             : 
     420             :         // METHODOLOGY EMPLOYED:
     421             :         // na
     422             : 
     423             :         // REFERENCES:
     424             :         //       \field Reporting Frequency
     425             :         //       \type choice
     426             :         //       \key Detailed
     427             :         //       \note Detailed lists every instance (i.e. HVAC variable timesteps)
     428             :         //       \key Timestep
     429             :         //       \note Timestep refers to the zone Timestep/Number of Timesteps in hour value
     430             :         //       \note RunPeriod, Environment, and Annual are the same
     431             :         //       \key Hourly
     432             :         //       \key Daily
     433             :         //       \key Monthly
     434             :         //       \key RunPeriod
     435             :         //       \key Environment
     436             :         //       \key Annual
     437             :         //       \default Hourly
     438             :         //       \note RunPeriod and Environment are synonymous
     439             : 
     440             :         // Locals
     441             :         // SUBROUTINE ARGUMENT DEFINITIONS:
     442             : 
     443             :         // SUBROUTINE PARAMETER DEFINITIONS:
     444       26991 :         static std::vector<std::string> const PossibleFreqs({"DETA", "TIME", "HOUR", "DAIL", "MONT", "RUNP", "ENVI", "ANNU"});
     445             :         //=(/'detail','Timestep','Hourly','Daily','Monthly','RunPeriod','Environment','Annual'/)
     446             :         static std::vector<std::string> const ExactFreqStrings(
     447       26991 :             {"Detailed", "Timestep", "Hourly", "Daily", "Monthly", "RunPeriod", "Environment", "Annual"});
     448             :         static std::vector<std::string> const ExactFreqStringsUpper(
     449       26991 :             {"DETAILED", "TIMESTEP", "HOURLY", "DAILY", "MONTHLY", "RUNPERIOD", "ENVIRONMENT", "ANNUAL"});
     450             :         // Vector of the result, was { -1, 0, 1, 2, 3, 4, 4, 4 } before the addition of Yearly;
     451             :         static std::vector<ReportingFrequency> const FreqValues({ReportingFrequency::EachCall,
     452             :                                                                  ReportingFrequency::TimeStep,
     453             :                                                                  ReportingFrequency::Hourly,
     454             :                                                                  ReportingFrequency::Daily,
     455             :                                                                  ReportingFrequency::Monthly,
     456             :                                                                  ReportingFrequency::Simulation,
     457             :                                                                  ReportingFrequency::Simulation,
     458       26991 :                                                                  ReportingFrequency::Yearly});
     459             :         // note: runperiod and environment are synonomous
     460             : 
     461             :         // INTERFACE BLOCK SPECIFICATIONS:
     462             :         // na
     463             : 
     464             :         // DERIVED TYPE DEFINITIONS:
     465             :         // na
     466             : 
     467             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     468             : 
     469       26991 :         ReportingFrequency ReportFreq(ReportingFrequency::Hourly); // Default
     470             :         // TODO: I think it's supposed to be upper case already, but tests aren't doing that at least...
     471       53982 :         const std::string FreqStringUpper = UtilityRoutines::MakeUPPERCase(FreqString);
     472       26991 :         std::string::size_type const LenString = min(len(FreqString), static_cast<std::string::size_type>(4u));
     473             : 
     474       26991 :         if (LenString < 4u) {
     475           8 :             return ReportFreq;
     476             :         }
     477             : 
     478       53966 :         std::string const FreqStringTrim(FreqStringUpper.substr(0, LenString));
     479       89206 :         for (unsigned Loop = 0; Loop < FreqValues.size(); ++Loop) {
     480       89206 :             if (FreqStringTrim == PossibleFreqs[Loop]) {
     481       26983 :                 if (FreqStringUpper != ExactFreqStringsUpper[Loop]) {
     482           0 :                     ShowWarningError(state, format("DetermineFrequency: Entered frequency=\"{}\" is not an exact match to key strings.", FreqString));
     483           0 :                     ShowContinueError(state, format("Frequency={} will be used.", ExactFreqStrings[Loop]));
     484             :                 }
     485       26983 :                 ReportFreq = std::max(FreqValues[Loop], state.dataOutputProcessor->minimumReportFrequency);
     486       26983 :                 break;
     487             :             }
     488             :         }
     489       26983 :         return ReportFreq;
     490             :     }
     491             : 
     492     6082900 :     void GetReportVariableInput(EnergyPlusData &state)
     493             :     {
     494             : 
     495             :         // SUBROUTINE INFORMATION:
     496             :         //       AUTHOR         Linda K. Lawrie
     497             :         //       DATE WRITTEN   December 1998
     498             :         //       MODIFIED       December 2017; Jason DeGraw
     499             :         //       RE-ENGINEERED  na
     500             : 
     501             :         // PURPOSE OF THIS SUBROUTINE:
     502             :         // This subroutine gets the requested report variables from
     503             :         // the input file.
     504             :         // Report Variable,
     505             :         //        \memo each Report Variable command picks variables to be put onto the standard output file (.eso)
     506             :         //        \memo some variables may not be reported for every simulation
     507             :         //   A1 , \field Key_Value
     508             :         //        \note use '*' (without quotes) to apply this variable to all keys
     509             :         //   A2 , \field Variable_Name
     510             :         //   A3 , \field Reporting_Frequency
     511             :         //        \type choice
     512             :         //        \key detailed
     513             :         //        \key timestep
     514             :         //        \key hourly
     515             :         //        \key daily
     516             :         //        \key monthly
     517             :         //        \key runperiod
     518             :         //   A4 ; \field Schedule_Name
     519             :         //        \type object-list
     520             :         //        \object-list ScheduleNames
     521             : 
     522             :         // Using/Aliasing
     523             :         using ScheduleManager::GetScheduleIndex;
     524             : 
     525             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     526             :         int Loop;
     527             :         int NumAlpha;
     528             :         int NumNumbers;
     529             :         int IOStat;
     530     6082900 :         bool ErrorsFound(false); // If errors detected in input
     531     6083671 :         std::string cCurrentModuleObject;
     532     6083671 :         Array1D_string cAlphaArgs(4);
     533     6083671 :         Array1D_string cAlphaFieldNames(4);
     534     6083671 :         Array1D_bool lAlphaFieldBlanks(4);
     535     6083671 :         Array1D<Real64> rNumericArgs(1);
     536     6083671 :         Array1D_string cNumericFieldNames(1);
     537     6083671 :         Array1D_bool lNumericFieldBlanks(1);
     538     6082900 :         auto &op(state.dataOutputProcessor);
     539             : 
     540             :         // Bail out if the input has already been read in
     541     6082900 :         if (!op->GetOutputInputFlag) {
     542     6082129 :             return;
     543             :         }
     544         771 :         op->GetOutputInputFlag = false;
     545             : 
     546             :         // First check environment variable to see of possible override for minimum reporting frequency
     547         771 :         if (!state.dataSysVars->MinReportFrequency.empty()) {
     548             :             // Formats
     549             :             static constexpr std::string_view Format_800("! <Minimum Reporting Frequency (overriding input value)>, Value, Input Value\n");
     550             :             static constexpr std::string_view Format_801(" Minimum Reporting Frequency, {},{}\n");
     551           0 :             op->minimumReportFrequency = determineFrequency(state, state.dataSysVars->MinReportFrequency);
     552           0 :             print(state.files.eio, Format_800);
     553           0 :             print(
     554           0 :                 state.files.eio, Format_801, frequencyNotice(StoreType::Averaged, op->minimumReportFrequency), state.dataSysVars->MinReportFrequency);
     555             :         }
     556             : 
     557         771 :         cCurrentModuleObject = "Output:Variable";
     558         771 :         op->NumOfReqVariables = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     559         771 :         op->ReqRepVars.allocate(op->NumOfReqVariables);
     560             : 
     561       21128 :         for (Loop = 1; Loop <= op->NumOfReqVariables; ++Loop) {
     562             : 
     563       20357 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     564             :                                                                      cCurrentModuleObject,
     565             :                                                                      Loop,
     566             :                                                                      cAlphaArgs,
     567             :                                                                      NumAlpha,
     568             :                                                                      rNumericArgs,
     569             :                                                                      NumNumbers,
     570             :                                                                      IOStat,
     571             :                                                                      lNumericFieldBlanks,
     572             :                                                                      lAlphaFieldBlanks,
     573             :                                                                      cAlphaFieldNames,
     574             :                                                                      cNumericFieldNames);
     575             : 
     576             :             // Check for duplicates?
     577       20357 :             auto &reqRepVar = op->ReqRepVars(Loop);
     578       20357 :             reqRepVar.Key = cAlphaArgs(1);
     579       20357 :             if (reqRepVar.Key == "*") {
     580       14867 :                 reqRepVar.Key = std::string();
     581             :             }
     582             : 
     583       20357 :             bool is_simple_string = !DataOutputs::isKeyRegexLike(reqRepVar.Key);
     584       20357 :             reqRepVar.is_simple_string = is_simple_string;
     585       20357 :             if (!is_simple_string) {
     586           0 :                 reqRepVar.case_insensitive_pattern = std::make_shared<RE2>("(?i)" + reqRepVar.Key);
     587             :             }
     588             : 
     589       20357 :             std::string::size_type const lbpos = index(cAlphaArgs(2), '['); // Remove Units designation if user put it in
     590       20357 :             if (lbpos != std::string::npos) {
     591           0 :                 cAlphaArgs(2).erase(lbpos);
     592             :                 // right trim
     593           0 :                 cAlphaArgs(2) = cAlphaArgs(2).substr(0, std::min(cAlphaArgs(2).find_last_not_of(" \f\n\r\t\v") + 1, cAlphaArgs(2).size()));
     594             :             }
     595       20357 :             reqRepVar.VarName = cAlphaArgs(2);
     596             : 
     597       20357 :             reqRepVar.frequency = determineFrequency(state, cAlphaArgs(3));
     598             : 
     599             :             // Schedule information
     600       20357 :             reqRepVar.SchedName = cAlphaArgs(4);
     601       20357 :             if (not_blank(reqRepVar.SchedName)) {
     602         635 :                 reqRepVar.SchedPtr = GetScheduleIndex(state, reqRepVar.SchedName);
     603         635 :                 if (reqRepVar.SchedPtr == 0) {
     604           0 :                     ShowSevereError(state,
     605           0 :                                     "GetReportVariableInput: " + cCurrentModuleObject + "=\"" + cAlphaArgs(1) + ':' + reqRepVar.VarName +
     606           0 :                                         "\" invalid " + cAlphaFieldNames(4) + "=\"" + reqRepVar.SchedName + "\" - not found.");
     607           0 :                     ErrorsFound = true;
     608             :                 }
     609             :             } else {
     610       19722 :                 reqRepVar.SchedPtr = 0;
     611             :             }
     612             : 
     613       20357 :             reqRepVar.Used = false;
     614             :         }
     615             : 
     616         771 :         if (ErrorsFound) {
     617           0 :             ShowFatalError(state, "GetReportVariableInput:" + cCurrentModuleObject + ": errors in input.");
     618             :         }
     619             :     }
     620             : 
     621      102114 :     void ProduceMinMaxString(std::string &String,                // Current value
     622             :                              int const DateValue,                // Date of min/max
     623             :                              ReportingFrequency const ReportFreq // Reporting Frequency
     624             :     )
     625             :     {
     626             : 
     627             :         // SUBROUTINE INFORMATION:
     628             :         //       AUTHOR         Linda K. Lawrie
     629             :         //       DATE WRITTEN   December 1998
     630             :         //       MODIFIED       na
     631             :         //       RE-ENGINEERED  na
     632             : 
     633             :         // PURPOSE OF THIS SUBROUTINE:
     634             :         // This subroutine produces the appropriate min/max string depending
     635             :         // on the reporting frequency.
     636             : 
     637             :         // METHODOLOGY EMPLOYED:
     638             :         // Prior to calling this routine, the basic value string will be
     639             :         // produced, but DecodeMonDayHrMin will not have been called.
     640             : 
     641             :         // REFERENCES:
     642             :         // na
     643             : 
     644             :         // Using/Aliasing
     645             :         using General::DecodeMonDayHrMin;
     646             : 
     647             :         // Locals
     648             :         // SUBROUTINE ARGUMENT DEFINITIONS:
     649             : 
     650             :         // SUBROUTINE PARAMETER DEFINITIONS:
     651             :         static constexpr std::string_view DayFormat("{},{:2},{:2}");
     652             :         static constexpr std::string_view MonthFormat("{},{:2},{:2},{:2}");
     653             :         static constexpr std::string_view EnvrnFormat("{},{:2},{:2},{:2},{:2}");
     654             : 
     655             :         // INTERFACE BLOCK SPECIFICATIONS:
     656             :         // na
     657             : 
     658             :         // DERIVED TYPE DEFINITIONS:
     659             :         // na
     660             : 
     661             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     662             :         int Mon;
     663             :         int Day;
     664             :         int Hour;
     665             :         int Minute;
     666      204228 :         std::string StrOut;
     667             : 
     668      102114 :         DecodeMonDayHrMin(DateValue, Mon, Day, Hour, Minute);
     669             : 
     670      102114 :         switch (ReportFreq) {
     671       20238 :         case ReportingFrequency::Daily:
     672       20238 :             StrOut = format(DayFormat, strip(String), Hour, Minute);
     673       20238 :             break;
     674       68740 :         case ReportingFrequency::Monthly:
     675       68740 :             StrOut = format(MonthFormat, strip(String), Day, Hour, Minute);
     676       68740 :             break;
     677       13136 :         case ReportingFrequency::Yearly:
     678             :         case ReportingFrequency::Simulation:
     679       13136 :             StrOut = format(EnvrnFormat, strip(String), Mon, Day, Hour, Minute);
     680       13136 :             break;
     681           0 :         default: // Each, TimeStep, Hourly dont have this
     682           0 :             StrOut = std::string();
     683           0 :             break;
     684             :         }
     685             : 
     686      102114 :         String = StrOut;
     687      102114 :     }
     688             : 
     689     6086118 :     TimeStepType ValidateTimeStepType(EnergyPlusData &state,
     690             :                                       OutputProcessor::SOVTimeStepType const TimeStepTypeKey) // Index type (Zone, HVAC) for variables
     691             :     {
     692             : 
     693             :         // FUNCTION INFORMATION:
     694             :         //       AUTHOR         Linda K. Lawrie
     695             :         //       DATE WRITTEN   December 1998
     696             :         //       MODIFIED       na
     697             :         //       RE-ENGINEERED  na
     698             : 
     699             :         // PURPOSE OF THIS FUNCTION:
     700             :         // This function validates the requested "index" type and returns
     701             :         // the proper value for use inside the OutputProcessor.
     702             : 
     703             :         // METHODOLOGY EMPLOYED:
     704             :         // Look it up in a list of valid index types.
     705     6086118 :         switch (TimeStepTypeKey) {
     706     4095581 :         case OutputProcessor::SOVTimeStepType::Zone:
     707     4095581 :             return TimeStepType::Zone;
     708     1990537 :         case OutputProcessor::SOVTimeStepType::HVAC:
     709             :         case OutputProcessor::SOVTimeStepType::System:
     710             :         case OutputProcessor::SOVTimeStepType::Plant:
     711     1990537 :             return TimeStepType::System;
     712           0 :         case OutputProcessor::SOVTimeStepType::Invalid:
     713             :         case OutputProcessor::SOVTimeStepType::Num:
     714           0 :             ShowFatalError(state, "Bad SOVTimeStepType passed to ValidateTimeStepType");
     715             :         }
     716           0 :         return TimeStepType::System; // compiler doesn't understand that ShowFatalError aborts
     717             :     }
     718             : 
     719      875230 :     std::string StandardTimeStepTypeKey(TimeStepType const timeStepType)
     720             :     {
     721             : 
     722             :         // FUNCTION INFORMATION:
     723             :         //       AUTHOR         Linda K. Lawrie
     724             :         //       DATE WRITTEN   December 1998
     725             :         //       MODIFIED       na
     726             :         //       RE-ENGINEERED  na
     727             : 
     728             :         // PURPOSE OF THIS FUNCTION:
     729             :         // This function gives the standard string for the index type
     730             :         // given.
     731             : 
     732             :         // METHODOLOGY EMPLOYED:
     733             :         // Look it up in a list of valid index types.
     734             : 
     735             :         // REFERENCES:
     736             :         // na
     737             : 
     738             :         // USE STATEMENTS:
     739             :         // na
     740             : 
     741             :         // Return value
     742      875230 :         std::string StandardTimeStepTypeKey;
     743             : 
     744             :         // Locals
     745             :         // FUNCTION ARGUMENT DEFINITIONS:
     746             : 
     747             :         // FUNCTION PARAMETER DEFINITIONS:
     748             :         // na
     749             : 
     750             :         // INTERFACE BLOCK SPECIFICATIONS:
     751             :         // na
     752             : 
     753             :         // DERIVED TYPE DEFINITIONS:
     754             :         // na
     755             : 
     756             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
     757             :         // na
     758             : 
     759      875230 :         if (timeStepType == TimeStepType::Zone) {
     760      509004 :             StandardTimeStepTypeKey = "Zone";
     761      366226 :         } else if (timeStepType == TimeStepType::System) {
     762      366226 :             StandardTimeStepTypeKey = "HVAC";
     763             :         } else {
     764           0 :             StandardTimeStepTypeKey = "UNKW";
     765             :         }
     766             : 
     767      875230 :         return StandardTimeStepTypeKey;
     768             :     }
     769             : 
     770     6084576 :     StoreType validateVariableType(EnergyPlusData &state, OutputProcessor::SOVStoreType const VariableTypeKey)
     771             :     {
     772             : 
     773             :         // FUNCTION INFORMATION:
     774             :         //       AUTHOR         Linda K. Lawrie
     775             :         //       DATE WRITTEN   December 1998
     776             :         //       MODIFIED       December 2017; Jason DeGraw
     777             :         //       RE-ENGINEERED  na
     778             : 
     779             :         // PURPOSE OF THIS FUNCTION:
     780             :         // This function validates the VariableTypeKey passed to the SetupVariable
     781             :         // routine and assigns it the value used in the OutputProcessor.
     782             : 
     783             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
     784     6084576 :         switch (VariableTypeKey) {
     785     4883795 :         case OutputProcessor::SOVStoreType::State:
     786             :         case OutputProcessor::SOVStoreType::Average:
     787     4883795 :             return StoreType::Averaged;
     788     1200781 :         case OutputProcessor::SOVStoreType::NonState:
     789             :         case OutputProcessor::SOVStoreType::Summed:
     790     1200781 :             return StoreType::Summed;
     791           0 :         case OutputProcessor::SOVStoreType::Invalid:
     792             :         case OutputProcessor::SOVStoreType::Num:
     793           0 :             ShowFatalError(state, "Bad SOVStoreType passed to validateVariableType");
     794             :         }
     795           0 :         return StoreType::Summed; // compiler doesn't understand that ShowFatalError aborts
     796             :     }
     797             : 
     798      875230 :     std::string standardVariableTypeKey(StoreType const VariableType)
     799             :     {
     800             : 
     801             :         // FUNCTION INFORMATION:
     802             :         //       AUTHOR         Linda K. Lawrie
     803             :         //       DATE WRITTEN   July 1999
     804             :         //       MODIFIED       December 2017; Jason DeGraw
     805             :         //       RE-ENGINEERED  na
     806             : 
     807             :         // PURPOSE OF THIS FUNCTION:
     808             :         // This function gives the standard string for the variable type
     809             :         // given.
     810             : 
     811             :         // METHODOLOGY EMPLOYED:
     812             :         // From variable type value, produce proper string.
     813             : 
     814             :         // REFERENCES:
     815             :         // na
     816             : 
     817             :         // USE STATEMENTS:
     818             :         // na
     819             : 
     820             :         // Return value
     821             :         // na
     822             : 
     823             :         // Locals
     824             :         // FUNCTION ARGUMENT DEFINITIONS:
     825             : 
     826             :         // FUNCTION PARAMETER DEFINITIONS:
     827             :         // na
     828             : 
     829             :         // INTERFACE BLOCK SPECIFICATIONS:
     830             :         // na
     831             : 
     832             :         // DERIVED TYPE DEFINITIONS:
     833             :         // na
     834             : 
     835             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
     836             :         // na
     837             : 
     838      875230 :         switch (VariableType) {
     839      555036 :         case StoreType::Averaged:
     840      555036 :             return "Average";
     841             :             break;
     842      320194 :         case StoreType::Summed:
     843      320194 :             return "Sum";
     844             :             break;
     845           0 :         default:
     846           0 :             return "Unknown";
     847             :         }
     848             :     }
     849             : 
     850             :     // *****************************************************************************
     851             :     // The following routines implement Energy Meters in EnergyPlus.
     852             :     // *****************************************************************************
     853             : 
     854         771 :     void InitializeMeters(EnergyPlusData &state)
     855             :     {
     856             : 
     857             :         // SUBROUTINE INFORMATION:
     858             :         //       AUTHOR         Linda Lawrie
     859             :         //       DATE WRITTEN   January 2001
     860             :         //       MODIFIED       na
     861             :         //       RE-ENGINEERED  na
     862             : 
     863             :         // PURPOSE OF THIS SUBROUTINE:
     864             :         // This subroutine creates the set of meters in EnergyPlus.  In this initial
     865             :         // implementation, it is a static set of meters.
     866             : 
     867             :         // METHODOLOGY EMPLOYED:
     868             :         // Allocate the static set.  Use "AddMeter" with appropriate arguments that will
     869             :         // allow expansion later.
     870             : 
     871             :         // REFERENCES:
     872             :         // na
     873             : 
     874             :         // USE STATEMENTS:
     875             :         // na
     876             : 
     877             :         // Locals
     878             :         // SUBROUTINE ARGUMENT DEFINITIONS:
     879             :         // na
     880             : 
     881             :         // SUBROUTINE PARAMETER DEFINITIONS:
     882             :         // na
     883             : 
     884             :         // INTERFACE BLOCK SPECIFICATIONS:
     885             :         // na
     886             : 
     887             :         // DERIVED TYPE DEFINITIONS:
     888             :         // na
     889             : 
     890             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     891             : 
     892         771 :         state.files.mtd.ensure_open(state, "InitializeMeters", state.files.outputControl.mtd);
     893         771 :     }
     894             : 
     895         769 :     void GetCustomMeterInput(EnergyPlusData &state, bool &ErrorsFound)
     896             :     {
     897             : 
     898             :         // SUBROUTINE INFORMATION:
     899             :         //       AUTHOR         Linda Lawrie
     900             :         //       DATE WRITTEN   January 2006
     901             :         //       MODIFIED       na
     902             :         //       RE-ENGINEERED  na
     903             : 
     904             :         // PURPOSE OF THIS SUBROUTINE:
     905             :         // This routine will help implement "custom"/user defined meters.  However, it must be called after all
     906             :         // the other meters are set up and all report variables are established.
     907             : 
     908             :         // METHODOLOGY EMPLOYED:
     909             :         // na
     910             : 
     911             :         // REFERENCES:
     912             :         // Processes the objects:
     913             :         // Meter:Custom,
     914             :         //    \extensible:2 - repeat last two fields, remembering to remove ; from "inner" fields.
     915             :         //    \memo Used to allow users to combine specific variables and/or meters into
     916             :         //    \memo "custom" meter configurations.
     917             :         //    A1,  \field Name
     918             :         //         \required-field
     919             :         //         \reference CustomMeterNames
     920             :         //    A2,  \field Fuel Type
     921             :         //         \type choice
     922             :         //         \key Electricity
     923             :         //         \key NaturalGas
     924             :         //         \key PropaneGas
     925             :         //         \key FuelOilNo1
     926             :         //         \key FuelOilNo2
     927             :         //         \key Coal
     928             :         //         \key Diesel
     929             :         //         \key Gasoline
     930             :         //         \key Water
     931             :         //         \key Generic
     932             :         //         \key OtherFuel1
     933             :         //         \key OtherFuel2
     934             :         //    A3,  \field Key Name 1
     935             :         //         \required-field
     936             :         //         \begin-extensible
     937             :         //    A4,  \field Report Variable or Meter Name 1
     938             :         //         \required-field
     939             :         // <etc>
     940             :         // AND
     941             :         // Meter:CustomDecrement,
     942             :         //    \extensible:2 - repeat last two fields, remembering to remove ; from "inner" fields.
     943             :         //    \memo Used to allow users to combine specific variables and/or meters into
     944             :         //    \memo "custom" meter configurations.
     945             :         //    A1,  \field Name
     946             :         //         \required-field
     947             :         //         \reference CustomMeterNames
     948             :         //    A2,  \field Fuel Type
     949             :         //         \type choice
     950             :         //         \key Electricity
     951             :         //         \key NaturalGas
     952             :         //         \key PropaneGas
     953             :         //         \key FuelOilNo1
     954             :         //         \key FuelOilNo2
     955             :         //         \key Coal
     956             :         //         \key Diesel
     957             :         //         \key Gasoline
     958             :         //         \key Water
     959             :         //         \key Generic
     960             :         //         \key OtherFuel1
     961             :         //         \key OtherFuel2
     962             :         //    A3,  \field Source Meter Name
     963             :         //         \required-field
     964             :         //    A4,  \field Key Name 1
     965             :         //         \required-field
     966             :         //         \begin-extensible
     967             :         //    A5,  \field Report Variable or Meter Name 1
     968             :         //         \required-field
     969             :         // <etc>
     970             : 
     971             :         // Using/Aliasing
     972             : 
     973             :         // Locals
     974             :         // SUBROUTINE ARGUMENT DEFINITIONS:
     975             : 
     976             :         // SUBROUTINE PARAMETER DEFINITIONS:
     977             :         // na
     978             : 
     979             :         // INTERFACE BLOCK SPECIFICATIONS:
     980             :         // na
     981             : 
     982             :         // DERIVED TYPE DEFINITIONS:
     983             :         // na
     984             : 
     985             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     986         769 :         auto &op(state.dataOutputProcessor);
     987             :         int NumAlpha;
     988             :         int NumNumbers;
     989             :         int Loop;
     990             :         int IOStat;
     991             :         int NumCustomMeters;
     992             :         int NumCustomDecMeters;
     993             :         int fldIndex;
     994             :         bool KeyIsStar;
     995        1538 :         Array1D_string NamesOfKeys;                                    // Specific key name
     996        1538 :         Array1D_int IndexesForKeyVar;                                  // Array index
     997         769 :         OutputProcessor::Unit UnitsVar(OutputProcessor::Unit::None);   // Units enumeration
     998         769 :         OutputProcessor::Unit MeterUnits(OutputProcessor::Unit::None); // Units enumeration
     999             :         int KeyCount;
    1000             :         VariableType TypeVar;
    1001             :         OutputProcessor::StoreType AvgSumVar;
    1002             :         OutputProcessor::TimeStepType StepTypeVar;
    1003             :         int iKey;
    1004             :         int iKey1;
    1005             :         bool MeterCreated;
    1006        1538 :         Array1D_int VarsOnCustomMeter;
    1007             :         int MaxVarsOnCustomMeter;
    1008             :         int NumVarsOnCustomMeter;
    1009        1538 :         Array1D_int VarsOnSourceMeter;
    1010             :         int MaxVarsOnSourceMeter;
    1011             :         int NumVarsOnSourceMeter;
    1012             :         int iOnMeter;
    1013             :         int WhichMeter;
    1014             :         bool errFlag;
    1015             :         bool BigErrorsFound;
    1016             :         bool testa;
    1017             :         bool testb;
    1018             :         bool Tagged; // variable is appropriate to put on meter
    1019             :         std::string::size_type lbrackPos;
    1020             : 
    1021         769 :         BigErrorsFound = false;
    1022         769 :         auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
    1023             : 
    1024         769 :         cCurrentModuleObject = "Meter:Custom";
    1025         769 :         NumCustomMeters = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    1026             : 
    1027             :         // make list of names for all Meter:Custom since they cannot refer to other Meter:Custom's
    1028        1538 :         std::unordered_set<std::string> namesOfMeterCustom;
    1029         769 :         namesOfMeterCustom.reserve(NumCustomMeters);
    1030             : 
    1031         860 :         for (Loop = 1; Loop <= NumCustomMeters; ++Loop) {
    1032         637 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1033             :                                                                      cCurrentModuleObject,
    1034             :                                                                      Loop,
    1035          91 :                                                                      state.dataIPShortCut->cAlphaArgs,
    1036             :                                                                      NumAlpha,
    1037          91 :                                                                      state.dataIPShortCut->rNumericArgs,
    1038             :                                                                      NumNumbers,
    1039             :                                                                      IOStat,
    1040          91 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    1041          91 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    1042          91 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    1043          91 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    1044          91 :             namesOfMeterCustom.emplace(UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(1)));
    1045             :         }
    1046             : 
    1047         860 :         for (Loop = 1; Loop <= NumCustomMeters; ++Loop) {
    1048         637 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1049             :                                                                      cCurrentModuleObject,
    1050             :                                                                      Loop,
    1051          91 :                                                                      state.dataIPShortCut->cAlphaArgs,
    1052             :                                                                      NumAlpha,
    1053          91 :                                                                      state.dataIPShortCut->rNumericArgs,
    1054             :                                                                      NumNumbers,
    1055             :                                                                      IOStat,
    1056          91 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    1057          91 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    1058          91 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    1059          91 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    1060          91 :             lbrackPos = index(state.dataIPShortCut->cAlphaArgs(1), '[');
    1061          91 :             if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(1).erase(lbrackPos);
    1062          91 :             MeterCreated = false;
    1063         182 :             if (GlobalNames::VerifyUniqueInterObjectName(state,
    1064          91 :                                                          op->UniqueMeterNames,
    1065          91 :                                                          state.dataIPShortCut->cAlphaArgs(1),
    1066             :                                                          cCurrentModuleObject,
    1067          91 :                                                          state.dataIPShortCut->cAlphaFieldNames(1),
    1068             :                                                          ErrorsFound)) {
    1069           0 :                 continue;
    1070             :             }
    1071          91 :             if (allocated(VarsOnCustomMeter)) VarsOnCustomMeter.deallocate();
    1072          91 :             VarsOnCustomMeter.allocate(1000);
    1073          91 :             VarsOnCustomMeter = 0;
    1074          91 :             MaxVarsOnCustomMeter = 1000;
    1075          91 :             NumVarsOnCustomMeter = 0;
    1076             :             // check if any fields reference another Meter:Custom
    1077          91 :             int found = 0;
    1078         450 :             for (fldIndex = 4; fldIndex <= NumAlpha; fldIndex += 2) {
    1079         359 :                 if (namesOfMeterCustom.find(UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(fldIndex))) != namesOfMeterCustom.end()) {
    1080           0 :                     found = fldIndex;
    1081           0 :                     break;
    1082             :                 }
    1083             :             }
    1084          91 :             if (found != 0) {
    1085           0 :                 ShowWarningError(state,
    1086           0 :                                  cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", contains a reference to another " +
    1087           0 :                                      cCurrentModuleObject + " in field: " + state.dataIPShortCut->cAlphaFieldNames(found) + "=\"" +
    1088           0 :                                      state.dataIPShortCut->cAlphaArgs(found) + "\".");
    1089           0 :                 continue;
    1090             :             }
    1091             : 
    1092         450 :             for (fldIndex = 3; fldIndex <= NumAlpha; fldIndex += 2) {
    1093         359 :                 if (state.dataIPShortCut->cAlphaArgs(fldIndex) == "*" || state.dataIPShortCut->lAlphaFieldBlanks(fldIndex)) {
    1094          58 :                     KeyIsStar = true;
    1095          58 :                     state.dataIPShortCut->cAlphaArgs(fldIndex) = "*";
    1096             :                 } else {
    1097         301 :                     KeyIsStar = false;
    1098             :                 }
    1099         359 :                 if (state.dataIPShortCut->lAlphaFieldBlanks(fldIndex + 1)) {
    1100           0 :                     ShowSevereError(state,
    1101           0 :                                     cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", blank " +
    1102           0 :                                         state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + '.');
    1103           0 :                     ShowContinueError(state, "...cannot create custom meter.");
    1104           0 :                     BigErrorsFound = true;
    1105           0 :                     continue;
    1106             :                 }
    1107         359 :                 if (BigErrorsFound) continue;
    1108             :                 // Don't build/check things out if there were errors anywhere.  Use "GetVariableKeys" to map to actual variables...
    1109         359 :                 lbrackPos = index(state.dataIPShortCut->cAlphaArgs(fldIndex + 1), '[');
    1110         359 :                 if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(fldIndex + 1).erase(lbrackPos);
    1111         359 :                 Tagged = false;
    1112         359 :                 GetVariableKeyCountandType(
    1113         359 :                     state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), KeyCount, TypeVar, AvgSumVar, StepTypeVar, UnitsVar);
    1114         359 :                 if (TypeVar == VariableType::NotFound) {
    1115           0 :                     ShowWarningError(state,
    1116           0 :                                      cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
    1117           0 :                                          state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
    1118           0 :                                          state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
    1119           0 :                     ShowContinueError(state, "...will not be shown with the Meter results.");
    1120           0 :                     continue;
    1121             :                 }
    1122         359 :                 if (!MeterCreated) {
    1123          91 :                     MeterUnits = UnitsVar; // meter units are same as first variable on custom meter
    1124          91 :                     AddMeter(state, state.dataIPShortCut->cAlphaArgs(1), UnitsVar, std::string(), std::string(), std::string(), std::string());
    1125          91 :                     op->EnergyMeters(op->NumEnergyMeters).TypeOfMeter = MtrType::Custom;
    1126             :                     // Can't use resource type in AddMeter cause it will confuse it with other meters.  So, now:
    1127          91 :                     GetStandardMeterResourceType(state,
    1128          91 :                                                  op->EnergyMeters(op->NumEnergyMeters).ResourceType,
    1129         182 :                                                  UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(2)),
    1130             :                                                  errFlag);
    1131          91 :                     if (errFlag) {
    1132           0 :                         ShowContinueError(state, "..on " + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\".");
    1133           0 :                         BigErrorsFound = true;
    1134             :                     }
    1135         273 :                     DetermineMeterIPUnits(state,
    1136          91 :                                           op->EnergyMeters(op->NumEnergyMeters).RT_forIPUnits,
    1137          91 :                                           op->EnergyMeters(op->NumEnergyMeters).ResourceType,
    1138             :                                           UnitsVar,
    1139             :                                           errFlag);
    1140          91 :                     if (errFlag) {
    1141           1 :                         ShowContinueError(state, "..on " + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\".");
    1142           1 :                         ShowContinueError(state, "..requests for IP units from this meter will be ignored.");
    1143             :                     }
    1144             :                     //        EnergyMeters(NumEnergyMeters)%RT_forIPUnits=DetermineMeterIPUnits(EnergyMeters(NumEnergyMeters)%ResourceType,UnitsVar)
    1145          91 :                     MeterCreated = true;
    1146             :                 }
    1147         359 :                 if (UnitsVar != MeterUnits) {
    1148           0 :                     ShowWarningError(state,
    1149           0 :                                      cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", differing units in " +
    1150           0 :                                          state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
    1151           0 :                                          state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
    1152           0 :                     ShowContinueError(state,
    1153           0 :                                       "...will not be shown with the Meter results; units for meter=" + unitEnumToString(MeterUnits) +
    1154           0 :                                           ", units for this variable=" + unitEnumToString(UnitsVar) + '.');
    1155           0 :                     continue;
    1156             :                 }
    1157         359 :                 if ((TypeVar == VariableType::Real || TypeVar == VariableType::Integer) && AvgSumVar == StoreType::Summed) {
    1158         314 :                     Tagged = true;
    1159         314 :                     NamesOfKeys.allocate(KeyCount);
    1160         314 :                     IndexesForKeyVar.allocate(KeyCount);
    1161         314 :                     GetVariableKeys(state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), TypeVar, NamesOfKeys, IndexesForKeyVar);
    1162         314 :                     iOnMeter = 0;
    1163         314 :                     if (KeyIsStar) {
    1164          26 :                         for (iKey = 1; iKey <= KeyCount; ++iKey) {
    1165          13 :                             ++NumVarsOnCustomMeter;
    1166          13 :                             if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
    1167           0 :                                 VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
    1168             :                             }
    1169          13 :                             VarsOnCustomMeter(NumVarsOnCustomMeter) = IndexesForKeyVar(iKey);
    1170          13 :                             iOnMeter = 1;
    1171             :                         }
    1172          13 :                         if (iOnMeter == 0) {
    1173           0 :                             ShowSevereError(state,
    1174           0 :                                             cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid (all keys) " +
    1175           0 :                                                 state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
    1176           0 :                                                 state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
    1177           0 :                             ErrorsFound = true;
    1178             :                         }
    1179             :                     } else { // Key is not "*"
    1180        6610 :                         for (iKey = 1; iKey <= KeyCount; ++iKey) {
    1181        6309 :                             if (NamesOfKeys(iKey) != state.dataIPShortCut->cAlphaArgs(fldIndex)) continue;
    1182         301 :                             ++NumVarsOnCustomMeter;
    1183         301 :                             if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
    1184           0 :                                 VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
    1185             :                             }
    1186         301 :                             VarsOnCustomMeter(NumVarsOnCustomMeter) = IndexesForKeyVar(iKey);
    1187         301 :                             iOnMeter = 1;
    1188             :                         }
    1189         301 :                         if (iOnMeter == 0) {
    1190           0 :                             ShowSevereError(state,
    1191           0 :                                             cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
    1192           0 :                                                 state.dataIPShortCut->cAlphaArgs(fldIndex) + ':' + state.dataIPShortCut->cAlphaArgs(fldIndex + 1));
    1193           0 :                             ErrorsFound = true;
    1194             :                         }
    1195             :                     }
    1196         314 :                     NamesOfKeys.deallocate();
    1197         314 :                     IndexesForKeyVar.deallocate();
    1198             :                 }
    1199         359 :                 if (TypeVar == VariableType::Meter && AvgSumVar == StoreType::Summed) {
    1200          45 :                     Tagged = true;
    1201          45 :                     NamesOfKeys.allocate(KeyCount);
    1202          45 :                     IndexesForKeyVar.allocate(KeyCount);
    1203          45 :                     GetVariableKeys(state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), TypeVar, NamesOfKeys, IndexesForKeyVar);
    1204          45 :                     WhichMeter = IndexesForKeyVar(1);
    1205          45 :                     NamesOfKeys.deallocate();
    1206          45 :                     IndexesForKeyVar.deallocate();
    1207             :                     // for meters there will only be one key...  but it has variables associated...
    1208        2045 :                     for (iOnMeter = 1; iOnMeter <= op->NumVarMeterArrays; ++iOnMeter) {
    1209        2000 :                         if (!any_eq(op->VarMeterArrays(iOnMeter).OnMeters, WhichMeter)) continue;
    1210         324 :                         ++NumVarsOnCustomMeter;
    1211         324 :                         if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
    1212           0 :                             VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
    1213             :                         }
    1214         324 :                         VarsOnCustomMeter(NumVarsOnCustomMeter) = op->VarMeterArrays(iOnMeter).RepVariable;
    1215             :                     }
    1216             :                 }
    1217         359 :                 if (!Tagged) { // couldn't find place for this item on a meter
    1218           0 :                     if (AvgSumVar != StoreType::Summed) {
    1219           0 :                         ShowWarningError(state,
    1220           0 :                                          cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", variable not summed variable " +
    1221           0 :                                              state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
    1222           0 :                                              state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
    1223           0 :                         ShowContinueError(state,
    1224           0 :                                           "...will not be shown with the Meter results; units for meter=" + unitEnumToString(MeterUnits) +
    1225           0 :                                               ", units for this variable=" + unitEnumToString(UnitsVar) + '.');
    1226             :                     }
    1227             :                 }
    1228             :             }
    1229             :             // Check for duplicates
    1230         729 :             for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
    1231         638 :                 if (VarsOnCustomMeter(iKey) == 0) continue;
    1232        5083 :                 for (iKey1 = iKey + 1; iKey1 <= NumVarsOnCustomMeter; ++iKey1) {
    1233        4445 :                     if (iKey == iKey1) continue;
    1234        4445 :                     if (VarsOnCustomMeter(iKey) != VarsOnCustomMeter(iKey1)) continue;
    1235           0 :                     ShowWarningError(state,
    1236           0 :                                      cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", duplicate name=\"" +
    1237           0 :                                          op->RVariableTypes(VarsOnCustomMeter(iKey1)).VarName + "\".");
    1238           0 :                     ShowContinueError(state, "...only one value with this name will be shown with the Meter results.");
    1239           0 :                     VarsOnCustomMeter(iKey1) = 0;
    1240             :                 }
    1241             :             }
    1242         729 :             for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
    1243         638 :                 if (VarsOnCustomMeter(iKey) == 0) continue;
    1244         638 :                 auto &tmpVar = op->RVariableTypes(VarsOnCustomMeter(iKey)).VarPtr;
    1245         638 :                 AttachCustomMeters(state, VarsOnCustomMeter(iKey), tmpVar.MeterArrayPtr, op->NumEnergyMeters);
    1246             :             }
    1247          91 :             if (NumVarsOnCustomMeter == 0) {
    1248           0 :                 ShowWarningError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", no items assigned ");
    1249           0 :                 ShowContinueError(
    1250             :                     state, "...will not be shown with the Meter results. This may be caused by a Meter:Custom be assigned to another Meter:Custom.");
    1251             :             }
    1252             :         }
    1253             : 
    1254         769 :         cCurrentModuleObject = "Meter:CustomDecrement";
    1255         769 :         NumCustomDecMeters = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    1256             : 
    1257         807 :         for (Loop = 1; Loop <= NumCustomDecMeters; ++Loop) {
    1258         266 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1259             :                                                                      cCurrentModuleObject,
    1260             :                                                                      Loop,
    1261          38 :                                                                      state.dataIPShortCut->cAlphaArgs,
    1262             :                                                                      NumAlpha,
    1263          38 :                                                                      state.dataIPShortCut->rNumericArgs,
    1264             :                                                                      NumNumbers,
    1265             :                                                                      IOStat,
    1266          38 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    1267          38 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    1268          38 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    1269          38 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    1270          38 :             lbrackPos = index(state.dataIPShortCut->cAlphaArgs(1), '[');
    1271          38 :             if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(1).erase(lbrackPos);
    1272          38 :             MeterCreated = false;
    1273          76 :             if (GlobalNames::VerifyUniqueInterObjectName(state,
    1274          38 :                                                          op->UniqueMeterNames,
    1275          38 :                                                          state.dataIPShortCut->cAlphaArgs(1),
    1276             :                                                          cCurrentModuleObject,
    1277          38 :                                                          state.dataIPShortCut->cAlphaFieldNames(1),
    1278             :                                                          ErrorsFound)) {
    1279           0 :                 continue;
    1280             :             }
    1281          38 :             if (allocated(VarsOnCustomMeter)) VarsOnCustomMeter.deallocate();
    1282          38 :             VarsOnCustomMeter.allocate(1000);
    1283          38 :             VarsOnCustomMeter = 0;
    1284          38 :             MaxVarsOnCustomMeter = 1000;
    1285          38 :             NumVarsOnCustomMeter = 0;
    1286             : 
    1287          38 :             lbrackPos = index(state.dataIPShortCut->cAlphaArgs(3), '[');
    1288          38 :             if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(1).erase(lbrackPos);
    1289          38 :             WhichMeter = UtilityRoutines::FindItem(state.dataIPShortCut->cAlphaArgs(3), op->EnergyMeters);
    1290          38 :             if (WhichMeter == 0) {
    1291           0 :                 ShowSevereError(state,
    1292           0 :                                 cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
    1293           0 :                                     state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" + state.dataIPShortCut->cAlphaArgs(3) + "\".");
    1294           0 :                 ErrorsFound = true;
    1295           0 :                 continue;
    1296             :             }
    1297             :             //  Set up array of Vars that are on the source meter (for later validation).
    1298          38 :             if (allocated(VarsOnSourceMeter)) VarsOnSourceMeter.deallocate();
    1299          38 :             VarsOnSourceMeter.allocate(1000);
    1300          38 :             VarsOnSourceMeter = 0;
    1301          38 :             MaxVarsOnSourceMeter = 1000;
    1302          38 :             NumVarsOnSourceMeter = 0;
    1303        5730 :             for (iKey = 1; iKey <= op->NumVarMeterArrays; ++iKey) {
    1304        5692 :                 if (op->VarMeterArrays(iKey).NumOnMeters == 0 && op->VarMeterArrays(iKey).NumOnCustomMeters == 0) continue;
    1305             :                 //  On a meter
    1306        6278 :                 if (any_eq(op->VarMeterArrays(iKey).OnMeters, WhichMeter)) {
    1307         586 :                     ++NumVarsOnSourceMeter;
    1308         586 :                     if (NumVarsOnSourceMeter > MaxVarsOnSourceMeter) {
    1309           0 :                         VarsOnSourceMeter.redimension(MaxVarsOnSourceMeter += 100, 0);
    1310             :                     }
    1311         586 :                     VarsOnSourceMeter(NumVarsOnSourceMeter) = op->VarMeterArrays(iKey).RepVariable;
    1312         586 :                     continue;
    1313             :                 }
    1314        5106 :                 if (op->VarMeterArrays(iKey).NumOnCustomMeters == 0) continue;
    1315         156 :                 if (any_eq(op->VarMeterArrays(iKey).OnCustomMeters, WhichMeter)) {
    1316           0 :                     ++NumVarsOnSourceMeter;
    1317           0 :                     if (NumVarsOnSourceMeter > MaxVarsOnSourceMeter) {
    1318           0 :                         VarsOnSourceMeter.redimension(MaxVarsOnSourceMeter += 100, 0);
    1319             :                     }
    1320           0 :                     VarsOnSourceMeter(NumVarsOnSourceMeter) = op->VarMeterArrays(iKey).RepVariable;
    1321           0 :                     continue;
    1322             :                 }
    1323             :             }
    1324             : 
    1325          76 :             for (fldIndex = 4; fldIndex <= NumAlpha; fldIndex += 2) {
    1326          38 :                 if (state.dataIPShortCut->cAlphaArgs(fldIndex) == "*" || state.dataIPShortCut->lAlphaFieldBlanks(fldIndex)) {
    1327          34 :                     KeyIsStar = true;
    1328          34 :                     state.dataIPShortCut->cAlphaArgs(fldIndex) = "*";
    1329             :                 } else {
    1330           4 :                     KeyIsStar = false;
    1331             :                 }
    1332          38 :                 if (state.dataIPShortCut->lAlphaFieldBlanks(fldIndex + 1)) {
    1333           0 :                     ShowSevereError(state,
    1334           0 :                                     cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", blank " +
    1335           0 :                                         state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + '.');
    1336           0 :                     ShowContinueError(state, "...cannot create custom meter.");
    1337           0 :                     BigErrorsFound = true;
    1338           0 :                     continue;
    1339             :                 }
    1340          38 :                 if (BigErrorsFound) continue;
    1341          38 :                 Tagged = false;
    1342          38 :                 lbrackPos = index(state.dataIPShortCut->cAlphaArgs(fldIndex + 1), '[');
    1343          38 :                 if (lbrackPos != std::string::npos) state.dataIPShortCut->cAlphaArgs(fldIndex + 1).erase(lbrackPos);
    1344             :                 // Don't build/check things out if there were errors anywhere.  Use "GetVariableKeys" to map to actual variables...
    1345          38 :                 GetVariableKeyCountandType(
    1346          38 :                     state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), KeyCount, TypeVar, AvgSumVar, StepTypeVar, UnitsVar);
    1347          38 :                 if (TypeVar == VariableType::NotFound) {
    1348           0 :                     ShowWarningError(state,
    1349           0 :                                      cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
    1350           0 :                                          state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
    1351           0 :                                          state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
    1352           0 :                     ShowContinueError(state, "...will not be shown with the Meter results.");
    1353           0 :                     continue;
    1354             :                 }
    1355          38 :                 if (!MeterCreated) {
    1356          38 :                     MeterUnits = UnitsVar;
    1357          38 :                     AddMeter(state, state.dataIPShortCut->cAlphaArgs(1), UnitsVar, std::string(), std::string(), std::string(), std::string());
    1358          38 :                     op->EnergyMeters(op->NumEnergyMeters).TypeOfMeter = MtrType::CustomDec;
    1359          38 :                     op->EnergyMeters(op->NumEnergyMeters).SourceMeter = WhichMeter;
    1360             : 
    1361             :                     // Can't use resource type in AddMeter cause it will confuse it with other meters.  So, now:
    1362          38 :                     GetStandardMeterResourceType(state,
    1363          38 :                                                  op->EnergyMeters(op->NumEnergyMeters).ResourceType,
    1364          76 :                                                  UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(2)),
    1365             :                                                  errFlag);
    1366          38 :                     if (errFlag) {
    1367           0 :                         ShowContinueError(state, "..on " + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\".");
    1368           0 :                         BigErrorsFound = true;
    1369             :                     }
    1370         114 :                     DetermineMeterIPUnits(state,
    1371          38 :                                           op->EnergyMeters(op->NumEnergyMeters).RT_forIPUnits,
    1372          38 :                                           op->EnergyMeters(op->NumEnergyMeters).ResourceType,
    1373             :                                           UnitsVar,
    1374             :                                           errFlag);
    1375          38 :                     if (errFlag) {
    1376           0 :                         ShowContinueError(state, "..on " + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\".");
    1377           0 :                         ShowContinueError(state, "..requests for IP units from this meter will be ignored.");
    1378             :                     }
    1379             :                     //        EnergyMeters(NumEnergyMeters)%RT_forIPUnits=DetermineMeterIPUnits(EnergyMeters(NumEnergyMeters)%ResourceType,UnitsVar)
    1380          38 :                     MeterCreated = true;
    1381             :                 }
    1382          38 :                 if (UnitsVar != MeterUnits) {
    1383           0 :                     ShowWarningError(state,
    1384           0 :                                      cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", differing units in " +
    1385           0 :                                          state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
    1386           0 :                                          state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
    1387           0 :                     ShowContinueError(state,
    1388           0 :                                       "...will not be shown with the Meter results; units for meter=" + unitEnumToString(MeterUnits) +
    1389           0 :                                           ", units for this variable=" + unitEnumToString(UnitsVar) + '.');
    1390           0 :                     continue;
    1391             :                 }
    1392          38 :                 if ((TypeVar == VariableType::Real || TypeVar == VariableType::Integer) && AvgSumVar == StoreType::Summed) {
    1393           4 :                     Tagged = true;
    1394           4 :                     NamesOfKeys.allocate(KeyCount);
    1395           4 :                     IndexesForKeyVar.allocate(KeyCount);
    1396           4 :                     GetVariableKeys(state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), TypeVar, NamesOfKeys, IndexesForKeyVar);
    1397           4 :                     iOnMeter = 0;
    1398           4 :                     if (KeyIsStar) {
    1399           0 :                         for (iKey = 1; iKey <= KeyCount; ++iKey) {
    1400           0 :                             ++NumVarsOnCustomMeter;
    1401           0 :                             if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
    1402           0 :                                 VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
    1403             :                             }
    1404           0 :                             VarsOnCustomMeter(NumVarsOnCustomMeter) = IndexesForKeyVar(iKey);
    1405           0 :                             iOnMeter = 1;
    1406             :                         }
    1407           0 :                         if (iOnMeter == 0) {
    1408           0 :                             ShowSevereError(state,
    1409           0 :                                             cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid (all keys) " +
    1410           0 :                                                 state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
    1411           0 :                                                 state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
    1412           0 :                             ErrorsFound = true;
    1413             :                         }
    1414             :                     } else {
    1415         203 :                         for (iKey = 1; iKey <= KeyCount; ++iKey) {
    1416         199 :                             if (NamesOfKeys(iKey) != state.dataIPShortCut->cAlphaArgs(fldIndex)) continue;
    1417           4 :                             ++NumVarsOnCustomMeter;
    1418           4 :                             if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
    1419           0 :                                 VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
    1420             :                             }
    1421           4 :                             VarsOnCustomMeter(NumVarsOnCustomMeter) = IndexesForKeyVar(iKey);
    1422           4 :                             iOnMeter = 1;
    1423             :                         }
    1424           4 :                         if (iOnMeter == 0) {
    1425           0 :                             ShowSevereError(state,
    1426           0 :                                             cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " +
    1427           0 :                                                 state.dataIPShortCut->cAlphaArgs(fldIndex) + ':' + state.dataIPShortCut->cAlphaArgs(fldIndex + 1));
    1428           0 :                             ErrorsFound = true;
    1429             :                         }
    1430             :                     }
    1431           4 :                     NamesOfKeys.deallocate();
    1432           4 :                     IndexesForKeyVar.deallocate();
    1433             :                 }
    1434          38 :                 if (TypeVar == VariableType::Meter && AvgSumVar == StoreType::Summed) {
    1435          34 :                     Tagged = true;
    1436          34 :                     NamesOfKeys.allocate(KeyCount);
    1437          34 :                     IndexesForKeyVar.allocate(KeyCount);
    1438          34 :                     GetVariableKeys(state, state.dataIPShortCut->cAlphaArgs(fldIndex + 1), TypeVar, NamesOfKeys, IndexesForKeyVar);
    1439          34 :                     WhichMeter = IndexesForKeyVar(1);
    1440          34 :                     NamesOfKeys.deallocate();
    1441          34 :                     IndexesForKeyVar.deallocate();
    1442             :                     // for meters there will only be one key...  but it has variables associated...
    1443        2770 :                     for (iOnMeter = 1; iOnMeter <= op->NumVarMeterArrays; ++iOnMeter) {
    1444        2736 :                         testa = any_eq(op->VarMeterArrays(iOnMeter).OnMeters, WhichMeter);
    1445        2736 :                         testb = false;
    1446        2736 :                         if (op->VarMeterArrays(iOnMeter).NumOnCustomMeters > 0) {
    1447         459 :                             testb = any_eq(op->VarMeterArrays(iOnMeter).OnCustomMeters, WhichMeter);
    1448             :                         }
    1449        2736 :                         if (!(testa || testb)) continue;
    1450         169 :                         ++NumVarsOnCustomMeter;
    1451         169 :                         if (NumVarsOnCustomMeter > MaxVarsOnCustomMeter) {
    1452           0 :                             VarsOnCustomMeter.redimension(MaxVarsOnCustomMeter += 100, 0);
    1453             :                         }
    1454         169 :                         VarsOnCustomMeter(NumVarsOnCustomMeter) = op->VarMeterArrays(iOnMeter).RepVariable;
    1455             :                     }
    1456             :                 }
    1457          38 :                 if (!Tagged) { // couldn't find place for this item on a meter
    1458           0 :                     if (AvgSumVar != StoreType::Summed) {
    1459           0 :                         ShowWarningError(state,
    1460           0 :                                          cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", variable not summed variable " +
    1461           0 :                                              state.dataIPShortCut->cAlphaFieldNames(fldIndex + 1) + "=\"" +
    1462           0 :                                              state.dataIPShortCut->cAlphaArgs(fldIndex + 1) + "\".");
    1463           0 :                         ShowContinueError(state,
    1464           0 :                                           "...will not be shown with the Meter results; units for meter=" + unitEnumToString(MeterUnits) +
    1465           0 :                                               ", units for this variable=" + unitEnumToString(UnitsVar) + '.');
    1466             :                     }
    1467             :                 }
    1468             :             }
    1469             :             // Check for duplicates
    1470         211 :             for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
    1471         173 :                 if (VarsOnCustomMeter(iKey) == 0) continue;
    1472         515 :                 for (iKey1 = iKey + 1; iKey1 <= NumVarsOnCustomMeter; ++iKey1) {
    1473         342 :                     if (iKey == iKey1) continue;
    1474         342 :                     if (VarsOnCustomMeter(iKey) != VarsOnCustomMeter(iKey1)) continue;
    1475           0 :                     ShowWarningError(state,
    1476           0 :                                      cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", duplicate name=\"" +
    1477           0 :                                          op->RVariableTypes(VarsOnCustomMeter(iKey1)).VarName + "\".");
    1478           0 :                     ShowContinueError(state, "...only one value with this name will be shown with the Meter results.");
    1479           0 :                     VarsOnCustomMeter(iKey1) = 0;
    1480             :                 }
    1481             :             }
    1482         211 :             for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
    1483         173 :                 if (VarsOnCustomMeter(iKey) == 0) continue;
    1484         173 :                 auto &tmpVar = op->RVariableTypes(VarsOnCustomMeter(iKey)).VarPtr;
    1485         173 :                 AttachCustomMeters(state, VarsOnCustomMeter(iKey), tmpVar.MeterArrayPtr, op->NumEnergyMeters);
    1486             :             }
    1487             : 
    1488          38 :             errFlag = false;
    1489         211 :             for (iKey = 1; iKey <= NumVarsOnCustomMeter; ++iKey) {
    1490         173 :                 for (iKey1 = 1; iKey1 <= NumVarsOnSourceMeter; ++iKey1) {
    1491         173 :                     if (any_eq(VarsOnSourceMeter, VarsOnCustomMeter(iKey))) break;
    1492           0 :                     if (!errFlag) {
    1493           0 :                         ShowSevereError(state,
    1494           0 :                                         cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid specification to " +
    1495           0 :                                             state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" + state.dataIPShortCut->cAlphaArgs(3) + "\".");
    1496           0 :                         errFlag = true;
    1497             :                     }
    1498           0 :                     ShowContinueError(state, "..Variable=" + op->RVariableTypes(VarsOnCustomMeter(iKey)).VarName);
    1499           0 :                     ErrorsFound = true;
    1500           0 :                     break;
    1501             :                 }
    1502             :             }
    1503          38 :             if (NumVarsOnCustomMeter == 0) {
    1504           0 :                 ShowWarningError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", no items assigned ");
    1505           0 :                 ShowContinueError(state, "...will not be shown with the Meter results");
    1506             :             }
    1507             : 
    1508          38 :             VarsOnCustomMeter.deallocate();
    1509          38 :             VarsOnSourceMeter.deallocate();
    1510             :         }
    1511             : 
    1512         769 :         if (BigErrorsFound) ErrorsFound = true;
    1513         769 :     }
    1514             : 
    1515       56191 :     void GetStandardMeterResourceType(EnergyPlusData &state,
    1516             :                                       std::string &OutResourceType,
    1517             :                                       std::string const &UserInputResourceType, // Passed uppercase
    1518             :                                       bool &ErrorsFound)
    1519             :     {
    1520             : 
    1521             :         // SUBROUTINE INFORMATION:
    1522             :         //       AUTHOR         Linda Lawrie
    1523             :         //       DATE WRITTEN   April 2006
    1524             :         //       MODIFIED       na
    1525             :         //       RE-ENGINEERED  na
    1526             : 
    1527             :         // PURPOSE OF THIS SUBROUTINE:
    1528             :         // This routine compares the user input resource type with valid ones and returns
    1529             :         // the standard resource type.
    1530             : 
    1531       56191 :         ErrorsFound = false;
    1532             : 
    1533             :         // Basic ResourceType for Meters
    1534             :         {
    1535       56191 :             auto const &meterType(UserInputResourceType);
    1536             : 
    1537       56191 :             if (meterType == "ELECTRICITY") {
    1538       18854 :                 OutResourceType = "Electricity";
    1539             : 
    1540       37337 :             } else if (meterType == "NATURALGAS") {
    1541        2117 :                 OutResourceType = "NaturalGas";
    1542             : 
    1543       35220 :             } else if (meterType == "GASOLINE") {
    1544           2 :                 OutResourceType = "Gasoline";
    1545             : 
    1546       35218 :             } else if (meterType == "DIESEL") {
    1547          19 :                 OutResourceType = "Diesel";
    1548             : 
    1549       35199 :             } else if (meterType == "COAL") {
    1550           2 :                 OutResourceType = "Coal";
    1551             : 
    1552       35197 :             } else if (meterType == "FUELOILNO1") {
    1553           2 :                 OutResourceType = "FuelOilNo1";
    1554             : 
    1555       35195 :             } else if (meterType == "FUELOILNO2") {
    1556           5 :                 OutResourceType = "FuelOilNo2";
    1557             : 
    1558       35190 :             } else if (meterType == "PROPANE") {
    1559           2 :                 OutResourceType = "Propane";
    1560             : 
    1561       35188 :             } else if (meterType == "WATER" || meterType == "H2O") {
    1562        1495 :                 OutResourceType = "Water"; // this is water "use"
    1563             : 
    1564       33693 :             } else if (meterType == "ONSITEWATER" || meterType == "WATERPRODUCED" || meterType == "ONSITE WATER") {
    1565           4 :                 OutResourceType = "OnSiteWater"; // these are for supply record keeping
    1566             : 
    1567       33689 :             } else if (meterType == "MAINSWATER" || meterType == "WATERSUPPLY") {
    1568        1499 :                 OutResourceType = "MainsWater"; // record keeping
    1569             : 
    1570       32190 :             } else if (meterType == "RAINWATER" || meterType == "PRECIPITATION") {
    1571           0 :                 OutResourceType = "RainWater"; // record keeping
    1572             : 
    1573       32190 :             } else if (meterType == "WELLWATER" || meterType == "GROUNDWATER") {
    1574           0 :                 OutResourceType = "WellWater"; // record keeping
    1575             : 
    1576       32190 :             } else if (meterType == "CONDENSATE") {
    1577           0 :                 OutResourceType = "Condensate"; // record keeping
    1578             : 
    1579       32190 :             } else if (meterType == "ENERGYTRANSFER" || meterType == "ENERGYXFER" || meterType == "XFER") {
    1580       18486 :                 OutResourceType = "EnergyTransfer";
    1581             : 
    1582       13704 :             } else if (meterType == "STEAM") {
    1583           5 :                 OutResourceType = "Steam";
    1584             : 
    1585       13699 :             } else if (meterType == "DISTRICTCOOLING") {
    1586         349 :                 OutResourceType = "DistrictCooling";
    1587             : 
    1588       13350 :             } else if (meterType == "DISTRICTHEATING") {
    1589         396 :                 OutResourceType = "DistrictHeating";
    1590             : 
    1591       12954 :             } else if (meterType == "ELECTRICITYPRODUCED") {
    1592         107 :                 OutResourceType = "ElectricityProduced";
    1593             : 
    1594       12847 :             } else if (meterType == "ELECTRICITYPURCHASED") {
    1595         703 :                 OutResourceType = "ElectricityPurchased";
    1596             : 
    1597       12144 :             } else if (meterType == "ELECTRICITYSURPLUSSOLD") {
    1598         703 :                 OutResourceType = "ElectricitySurplusSold";
    1599             : 
    1600       11441 :             } else if (meterType == "ELECTRICITYNET") {
    1601         703 :                 OutResourceType = "ElectricityNet";
    1602             : 
    1603       10738 :             } else if (meterType == "SOLARWATER") {
    1604          19 :                 OutResourceType = "SolarWater";
    1605             : 
    1606       10719 :             } else if (meterType == "SOLARAIR") {
    1607          10 :                 OutResourceType = "SolarAir";
    1608             : 
    1609       10709 :             } else if (meterType == "SO2") {
    1610         204 :                 OutResourceType = "SO2";
    1611             : 
    1612       10505 :             } else if (meterType == "NOX") {
    1613         204 :                 OutResourceType = "NOx";
    1614             : 
    1615       10301 :             } else if (meterType == "N2O") {
    1616         204 :                 OutResourceType = "N2O";
    1617             : 
    1618       10097 :             } else if (meterType == "PM") {
    1619         204 :                 OutResourceType = "PM";
    1620             : 
    1621        9893 :             } else if (meterType == "PM2.5") {
    1622         204 :                 OutResourceType = "PM2.5";
    1623             : 
    1624        9689 :             } else if (meterType == "PM10") {
    1625         204 :                 OutResourceType = "PM10";
    1626             : 
    1627        9485 :             } else if (meterType == "CO") {
    1628         204 :                 OutResourceType = "CO";
    1629             : 
    1630        9281 :             } else if (meterType == "CO2") {
    1631         204 :                 OutResourceType = "CO2";
    1632             : 
    1633        9077 :             } else if (meterType == "CH4") {
    1634         204 :                 OutResourceType = "CH4";
    1635             : 
    1636        8873 :             } else if (meterType == "NH3") {
    1637         204 :                 OutResourceType = "NH3";
    1638             : 
    1639        8669 :             } else if (meterType == "NMVOC") {
    1640         204 :                 OutResourceType = "NMVOC";
    1641             : 
    1642        8465 :             } else if (meterType == "HG") {
    1643         204 :                 OutResourceType = "Hg";
    1644             : 
    1645        8261 :             } else if (meterType == "PB") {
    1646         204 :                 OutResourceType = "Pb";
    1647             : 
    1648        8057 :             } else if (meterType == "NUCLEAR HIGH") {
    1649         204 :                 OutResourceType = "Nuclear High";
    1650             : 
    1651        7853 :             } else if (meterType == "NUCLEAR LOW") {
    1652         204 :                 OutResourceType = "Nuclear Low";
    1653             : 
    1654        7649 :             } else if (meterType == "WATERENVIRONMENTALFACTORS") {
    1655         204 :                 OutResourceType = "WaterEnvironmentalFactors";
    1656             : 
    1657        7445 :             } else if (meterType == "CARBON EQUIVALENT") {
    1658        2307 :                 OutResourceType = "Carbon Equivalent";
    1659             : 
    1660        5138 :             } else if (meterType == "SOURCE") {
    1661         370 :                 OutResourceType = "Source";
    1662             : 
    1663        4768 :             } else if (meterType == "PLANTLOOPHEATINGDEMAND") {
    1664        3939 :                 OutResourceType = "PlantLoopHeatingDemand";
    1665             : 
    1666         829 :             } else if (meterType == "PLANTLOOPCOOLINGDEMAND") {
    1667         818 :                 OutResourceType = "PlantLoopCoolingDemand";
    1668             : 
    1669          11 :             } else if (meterType == "GENERIC") { // only used by custom meters
    1670           6 :                 OutResourceType = "Generic";
    1671             : 
    1672           5 :             } else if (meterType == "OTHERFUEL1") { // other fuel type (defined by user)
    1673           3 :                 OutResourceType = "OtherFuel1";
    1674             : 
    1675           2 :             } else if (meterType == "OTHERFUEL2") { // other fuel type (defined by user)
    1676           2 :                 OutResourceType = "OtherFuel2";
    1677             : 
    1678             :             } else {
    1679           0 :                 ShowSevereError(state, "GetStandardMeterResourceType: Illegal OutResourceType (for Meters) Entered=" + UserInputResourceType);
    1680           0 :                 ErrorsFound = true;
    1681             :             }
    1682             :         }
    1683       56191 :     }
    1684             : 
    1685       93065 :     void AddMeter(EnergyPlusData &state,
    1686             :                   std::string const &Name,              // Name for the meter
    1687             :                   OutputProcessor::Unit const MtrUnits, // Units for the meter
    1688             :                   std::string const &ResourceType,      // ResourceType for the meter
    1689             :                   std::string const &EndUse,            // EndUse for the meter
    1690             :                   std::string const &EndUseSub,         // EndUse subcategory for the meter
    1691             :                   std::string const &Group              // Group for the meter
    1692             :     )
    1693             :     {
    1694             : 
    1695             :         // SUBROUTINE INFORMATION:
    1696             :         //       AUTHOR         Linda Lawrie
    1697             :         //       DATE WRITTEN   January 2001
    1698             :         //       MODIFIED       na
    1699             :         //       RE-ENGINEERED  na
    1700             : 
    1701             :         // PURPOSE OF THIS SUBROUTINE:
    1702             :         // This subroutine adds a meter to the current definition set of meters.  If the maximum has
    1703             :         // already been reached, a reallocation procedure begins.  This action needs to be done at the
    1704             :         // start of the simulation, primarily before any output is stored.
    1705             : 
    1706             :         // Make sure this isn't already in the list of meter names
    1707       93065 :         auto &op(state.dataOutputProcessor);
    1708             :         int Found;
    1709             : 
    1710       93065 :         if (op->NumEnergyMeters > 0) {
    1711       92294 :             Found = UtilityRoutines::FindItemInList(Name, op->EnergyMeters);
    1712             :         } else {
    1713         771 :             Found = 0;
    1714             :         }
    1715             : 
    1716       93065 :         if (Found == 0) {
    1717       93065 :             op->EnergyMeters.redimension(++op->NumEnergyMeters);
    1718       93065 :             op->EnergyMeters(op->NumEnergyMeters).Name = Name;
    1719       93065 :             op->EnergyMeters(op->NumEnergyMeters).ResourceType = ResourceType;
    1720       93065 :             op->EnergyMeters(op->NumEnergyMeters).EndUse = EndUse;
    1721       93065 :             op->EnergyMeters(op->NumEnergyMeters).EndUseSub = EndUseSub;
    1722       93065 :             op->EnergyMeters(op->NumEnergyMeters).Group = Group;
    1723       93065 :             op->EnergyMeters(op->NumEnergyMeters).Units = MtrUnits;
    1724       93065 :             op->EnergyMeters(op->NumEnergyMeters).TSValue = 0.0;
    1725       93065 :             op->EnergyMeters(op->NumEnergyMeters).CurTSValue = 0.0;
    1726       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptTS = false;
    1727       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptTSFO = false;
    1728       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).TSRptNum);
    1729       93065 :             op->EnergyMeters(op->NumEnergyMeters).TSRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).TSRptNum);
    1730       93065 :             op->EnergyMeters(op->NumEnergyMeters).HRValue = 0.0;
    1731       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptHR = false;
    1732       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptHRFO = false;
    1733       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).HRRptNum);
    1734       93065 :             op->EnergyMeters(op->NumEnergyMeters).HRRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).HRRptNum);
    1735       93065 :             op->EnergyMeters(op->NumEnergyMeters).DYValue = 0.0;
    1736       93065 :             op->EnergyMeters(op->NumEnergyMeters).DYMaxVal = MaxSetValue;
    1737       93065 :             op->EnergyMeters(op->NumEnergyMeters).DYMaxValDate = 0;
    1738       93065 :             op->EnergyMeters(op->NumEnergyMeters).DYMinVal = MinSetValue;
    1739       93065 :             op->EnergyMeters(op->NumEnergyMeters).DYMinValDate = 0;
    1740       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptDY = false;
    1741       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptDYFO = false;
    1742       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).DYRptNum);
    1743       93065 :             op->EnergyMeters(op->NumEnergyMeters).DYRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).DYRptNum);
    1744       93065 :             op->EnergyMeters(op->NumEnergyMeters).MNValue = 0.0;
    1745       93065 :             op->EnergyMeters(op->NumEnergyMeters).MNMaxVal = MaxSetValue;
    1746       93065 :             op->EnergyMeters(op->NumEnergyMeters).MNMaxValDate = 0;
    1747       93065 :             op->EnergyMeters(op->NumEnergyMeters).MNMinVal = MinSetValue;
    1748       93065 :             op->EnergyMeters(op->NumEnergyMeters).MNMinValDate = 0;
    1749       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptMN = false;
    1750       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptMNFO = false;
    1751       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).MNRptNum);
    1752       93065 :             op->EnergyMeters(op->NumEnergyMeters).MNRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).MNRptNum);
    1753       93065 :             op->EnergyMeters(op->NumEnergyMeters).YRValue = 0.0;
    1754       93065 :             op->EnergyMeters(op->NumEnergyMeters).YRMaxVal = MaxSetValue;
    1755       93065 :             op->EnergyMeters(op->NumEnergyMeters).YRMaxValDate = 0;
    1756       93065 :             op->EnergyMeters(op->NumEnergyMeters).YRMinVal = MinSetValue;
    1757       93065 :             op->EnergyMeters(op->NumEnergyMeters).YRMinValDate = 0;
    1758       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptYR = false;
    1759       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptYRFO = false;
    1760       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).YRRptNum);
    1761       93065 :             op->EnergyMeters(op->NumEnergyMeters).YRRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).YRRptNum);
    1762       93065 :             op->EnergyMeters(op->NumEnergyMeters).SMValue = 0.0;
    1763       93065 :             op->EnergyMeters(op->NumEnergyMeters).SMMaxVal = MaxSetValue;
    1764       93065 :             op->EnergyMeters(op->NumEnergyMeters).SMMaxValDate = 0;
    1765       93065 :             op->EnergyMeters(op->NumEnergyMeters).SMMinVal = MinSetValue;
    1766       93065 :             op->EnergyMeters(op->NumEnergyMeters).SMMinValDate = 0;
    1767       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptSM = false;
    1768       93065 :             op->EnergyMeters(op->NumEnergyMeters).RptSMFO = false;
    1769       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).SMRptNum);
    1770       93065 :             op->EnergyMeters(op->NumEnergyMeters).SMRptNumChr = fmt::to_string(op->EnergyMeters(op->NumEnergyMeters).SMRptNum);
    1771       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).TSAccRptNum);
    1772       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).HRAccRptNum);
    1773       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).DYAccRptNum);
    1774       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).MNAccRptNum);
    1775       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).YRAccRptNum);
    1776       93065 :             AssignReportNumber(state, op->EnergyMeters(op->NumEnergyMeters).SMAccRptNum);
    1777       93065 :             op->EnergyMeters(op->NumEnergyMeters).FinYrSMValue = 0.0;
    1778       93065 :             op->EnergyMeters(op->NumEnergyMeters).FinYrSMMaxVal = MaxSetValue;
    1779       93065 :             op->EnergyMeters(op->NumEnergyMeters).FinYrSMMaxValDate = 0;
    1780       93065 :             op->EnergyMeters(op->NumEnergyMeters).FinYrSMMinVal = MinSetValue;
    1781       93065 :             op->EnergyMeters(op->NumEnergyMeters).FinYrSMMinValDate = 0;
    1782             :         } else {
    1783           0 :             ShowFatalError(state, "Requested to Add Meter which was already present=" + Name);
    1784             :         }
    1785       93065 :         if (!ResourceType.empty()) {
    1786             :             bool errFlag;
    1787       92936 :             DetermineMeterIPUnits(state, op->EnergyMeters(op->NumEnergyMeters).RT_forIPUnits, ResourceType, MtrUnits, errFlag);
    1788       92936 :             if (errFlag) {
    1789           0 :                 ShowContinueError(state, "..on Meter=\"" + Name + "\".");
    1790           0 :                 ShowContinueError(state, "..requests for IP units from this meter will be ignored.");
    1791             :             }
    1792             :         }
    1793       93065 :     }
    1794             : 
    1795       56062 :     void AttachMeters(EnergyPlusData &state,
    1796             :                       OutputProcessor::Unit const MtrUnits, // Units for this meter
    1797             :                       std::string &ResourceType,            // Electricity, Gas, etc.
    1798             :                       std::string &EndUse,                  // End-use category (Lights, Heating, etc.)
    1799             :                       std::string &EndUseSub,               // End-use subcategory (user-defined, e.g., General Lights, Task Lights, etc.)
    1800             :                       std::string &Group,                   // Group key (Facility, Zone, Building, etc.)
    1801             :                       std::string const &ZoneName,          // Zone key only applicable for Building group
    1802             :                       std::string const &SpaceType,         // Space Type key only applicable for Building group
    1803             :                       int const RepVarNum,                  // Number of this report variable
    1804             :                       int &MeterArrayPtr,                   // Output set of Pointers to Meters
    1805             :                       bool &ErrorsFound                     // True if errors in this call
    1806             :     )
    1807             :     {
    1808             : 
    1809             :         // SUBROUTINE INFORMATION:
    1810             :         //       AUTHOR         Linda Lawrie
    1811             :         //       DATE WRITTEN   January 2001
    1812             :         //       MODIFIED       na
    1813             :         //       RE-ENGINEERED  na
    1814             : 
    1815             :         // PURPOSE OF THIS SUBROUTINE:
    1816             :         // This subroutine determines which meters this variable will be on (if any),
    1817             :         // sets up the meter pointer arrays, and returns a index value to this array which
    1818             :         // is stored with the variable.
    1819             : 
    1820             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1821       56062 :         auto &op(state.dataOutputProcessor);
    1822             : 
    1823       56062 :         ValidateNStandardizeMeterTitles(state, MtrUnits, ResourceType, EndUse, EndUseSub, Group, ErrorsFound, ZoneName, SpaceType);
    1824             : 
    1825       56062 :         op->VarMeterArrays.redimension(++op->NumVarMeterArrays);
    1826       56062 :         MeterArrayPtr = op->NumVarMeterArrays;
    1827       56062 :         op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters = 0;
    1828       56062 :         op->VarMeterArrays(op->NumVarMeterArrays).RepVariable = RepVarNum;
    1829       56062 :         op->VarMeterArrays(op->NumVarMeterArrays).OnMeters = 0;
    1830       56062 :         int Found = UtilityRoutines::FindItem(ResourceType + ":Facility", op->EnergyMeters);
    1831       56062 :         if (Found != 0) {
    1832       56062 :             ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1833       56062 :             op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1834             :         }
    1835       56062 :         if (!Group.empty()) {
    1836       49880 :             Found = UtilityRoutines::FindItem(ResourceType + ':' + Group, op->EnergyMeters);
    1837       49880 :             if (Found != 0) {
    1838       49880 :                 ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1839       49880 :                 op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1840             :             }
    1841       49880 :             if (UtilityRoutines::SameString(Group, "Building")) { // Match to Zone and Space Type
    1842       19147 :                 if (!ZoneName.empty()) {
    1843       18825 :                     Found = UtilityRoutines::FindItem(ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
    1844       18825 :                     if (Found != 0) {
    1845       18825 :                         ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1846       18825 :                         op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1847             :                     }
    1848             :                 }
    1849       19147 :                 if (!SpaceType.empty()) {
    1850        8348 :                     Found = UtilityRoutines::FindItem(ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
    1851        8348 :                     if (Found != 0) {
    1852        8348 :                         ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1853        8348 :                         op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1854             :                     }
    1855             :                 }
    1856             :             }
    1857             :         }
    1858             : 
    1859             :         //!! Following if EndUse is by ResourceType
    1860       56062 :         if (!EndUse.empty()) {
    1861       56048 :             Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType, op->EnergyMeters);
    1862       56048 :             if (Found != 0) {
    1863       56048 :                 ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1864       56048 :                 op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1865             :             }
    1866       56048 :             if (UtilityRoutines::SameString(Group, "Building")) { // Match to Zone
    1867       19144 :                 if (!ZoneName.empty()) {
    1868       18825 :                     Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
    1869       18825 :                     if (Found != 0) {
    1870       18825 :                         ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1871       18825 :                         op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1872             :                     }
    1873             :                 }
    1874       19144 :                 if (!SpaceType.empty()) {
    1875        8348 :                     Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
    1876        8348 :                     if (Found != 0) {
    1877        8348 :                         ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1878        8348 :                         op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1879             : 
    1880        8348 :                         addEndUseSpaceType(state, EndUse, SpaceType);
    1881             :                     }
    1882             :                 }
    1883             :             }
    1884             : 
    1885             :             // End use subcategory
    1886       56048 :             if (!EndUseSub.empty()) {
    1887       39049 :                 Found = UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType, op->EnergyMeters);
    1888       39049 :                 if (Found != 0) {
    1889       39049 :                     ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1890       39049 :                     op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1891             : 
    1892       39049 :                     addEndUseSubcategory(state, EndUse, EndUseSub);
    1893             :                 }
    1894       39049 :                 if (UtilityRoutines::SameString(Group, "Building")) { // Match to Zone
    1895       19144 :                     if (!ZoneName.empty()) {
    1896       18825 :                         Found = UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
    1897       18825 :                         if (Found != 0) {
    1898       18825 :                             ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1899       18825 :                             op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1900             :                         }
    1901             :                     }
    1902       19144 :                     if (!SpaceType.empty()) {
    1903        8348 :                         Found =
    1904       16696 :                             UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
    1905        8348 :                         if (Found != 0) {
    1906        8348 :                             ++op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters;
    1907        8348 :                             op->VarMeterArrays(op->NumVarMeterArrays).OnMeters(op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters) = Found;
    1908             :                         }
    1909             :                     }
    1910             :                 }
    1911             :             }
    1912             :         }
    1913       56062 :     }
    1914             : 
    1915         811 :     void AttachCustomMeters(EnergyPlusData &state,
    1916             :                             int const RepVarNum, // Number of this report variable
    1917             :                             int &MeterArrayPtr,  // Input/Output set of Pointers to Meters
    1918             :                             int const MeterIndex // Which meter this is
    1919             :     )
    1920             :     {
    1921             : 
    1922             :         // SUBROUTINE INFORMATION:
    1923             :         //       AUTHOR         Linda Lawrie
    1924             :         //       DATE WRITTEN   January 2006
    1925             :         //       MODIFIED       na
    1926             :         //       RE-ENGINEERED  na
    1927             : 
    1928             :         // PURPOSE OF THIS SUBROUTINE:
    1929             :         // This subroutine determines which meters this variable will be on (if any),
    1930             :         // sets up the meter pointer arrays, and returns a index value to this array which
    1931             :         // is stored with the variable.
    1932             : 
    1933             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1934         811 :         auto &op(state.dataOutputProcessor);
    1935             : 
    1936         811 :         if (MeterArrayPtr == 0) {
    1937         161 :             op->VarMeterArrays.redimension(++op->NumVarMeterArrays);
    1938         161 :             MeterArrayPtr = op->NumVarMeterArrays;
    1939         161 :             op->VarMeterArrays(op->NumVarMeterArrays).NumOnMeters = 0;
    1940         161 :             op->VarMeterArrays(op->NumVarMeterArrays).RepVariable = RepVarNum;
    1941         161 :             op->VarMeterArrays(op->NumVarMeterArrays).OnMeters = 0;
    1942         161 :             op->VarMeterArrays(op->NumVarMeterArrays).OnCustomMeters.allocate(1);
    1943         161 :             op->VarMeterArrays(op->NumVarMeterArrays).NumOnCustomMeters = 1;
    1944             :         } else { // MeterArrayPtr set
    1945         650 :             op->VarMeterArrays(MeterArrayPtr).OnCustomMeters.redimension(++op->VarMeterArrays(MeterArrayPtr).NumOnCustomMeters);
    1946             :         }
    1947         811 :         op->VarMeterArrays(MeterArrayPtr).OnCustomMeters(op->VarMeterArrays(MeterArrayPtr).NumOnCustomMeters) = MeterIndex;
    1948         811 :     }
    1949             : 
    1950       56062 :     void ValidateNStandardizeMeterTitles(EnergyPlusData &state,
    1951             :                                          OutputProcessor::Unit const MtrUnits, // Units for the meter
    1952             :                                          std::string &ResourceType,            // Electricity, Gas, etc.
    1953             :                                          std::string &EndUse,                  // End Use Type (Lights, Heating, etc.)
    1954             :                                          std::string &EndUseSub,               // End Use Sub Type (General Lights, Task Lights, etc.)
    1955             :                                          std::string &Group,                   // Group key (Facility, Zone, Building, etc.)
    1956             :                                          bool &ErrorsFound,                    // True if errors in this call
    1957             :                                          const std::string &ZoneName,          // Zone Name when Group=Building
    1958             :                                          const std::string &SpaceType          // Space Type when Group=Building
    1959             :     )
    1960             :     {
    1961             : 
    1962             :         // SUBROUTINE INFORMATION:
    1963             :         //       AUTHOR         Linda Lawrie
    1964             :         //       DATE WRITTEN   January 2001
    1965             :         //       MODIFIED       na
    1966             :         //       RE-ENGINEERED  na
    1967             : 
    1968             :         // PURPOSE OF THIS SUBROUTINE:
    1969             :         // This subroutine uses the keys for the Energy Meters given to the SetupOutputVariable routines
    1970             :         // and makes sure they are "standard" as well as creating meters which need to be added as this
    1971             :         // is the first use of that kind of meter designation.
    1972             : 
    1973             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1974             :         int Found; // For checking whether meter is already defined
    1975       56062 :         bool LocalErrorsFound = false;
    1976      112124 :         std::string MeterName;
    1977       56062 :         auto &op(state.dataOutputProcessor);
    1978             : 
    1979             :         // Basic ResourceType Meters
    1980       56062 :         GetStandardMeterResourceType(state, ResourceType, UtilityRoutines::MakeUPPERCase(ResourceType), LocalErrorsFound);
    1981             : 
    1982       56062 :         if (!LocalErrorsFound) {
    1983       56062 :             if (op->NumEnergyMeters > 0) {
    1984       55291 :                 Found = UtilityRoutines::FindItem(ResourceType + ":Facility", op->EnergyMeters);
    1985             :             } else {
    1986         771 :                 Found = 0;
    1987             :             }
    1988       56062 :             if (Found == 0) AddMeter(state, ResourceType + ":Facility", MtrUnits, ResourceType, "", "", "");
    1989             :         }
    1990             : 
    1991             :         //!  Group Meters
    1992             :         {
    1993      112124 :             auto const groupMeter(uppercased(Group));
    1994             : 
    1995       56062 :             if (groupMeter.empty()) {
    1996             : 
    1997       49880 :             } else if (groupMeter == "BUILDING") {
    1998       19147 :                 Group = "Building";
    1999             : 
    2000       30733 :             } else if (groupMeter == "HVAC" || groupMeter == "SYSTEM") {
    2001       18961 :                 Group = "HVAC";
    2002             : 
    2003       11772 :             } else if (groupMeter == "PLANT") {
    2004       11772 :                 Group = "Plant";
    2005             : 
    2006             :             } else {
    2007           0 :                 ShowSevereError(state, "Illegal Group (for Meters) Entered=" + Group);
    2008           0 :                 LocalErrorsFound = true;
    2009             :             }
    2010             :         }
    2011             : 
    2012       56062 :         if (!LocalErrorsFound && !Group.empty()) {
    2013       49880 :             Found = UtilityRoutines::FindItem(ResourceType + ':' + Group, op->EnergyMeters);
    2014       49880 :             if (Found == 0) AddMeter(state, ResourceType + ':' + Group, MtrUnits, ResourceType, "", "", Group);
    2015       49880 :             if (Group == "Building") {
    2016       19147 :                 if (!ZoneName.empty()) {
    2017       18825 :                     Found = UtilityRoutines::FindItem(ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
    2018       18825 :                     if (Found == 0) {
    2019        9027 :                         AddMeter(state, ResourceType + ":Zone:" + ZoneName, MtrUnits, ResourceType, "", "", "Zone");
    2020             :                     }
    2021             :                 }
    2022       19147 :                 if (!SpaceType.empty()) {
    2023        8348 :                     Found = UtilityRoutines::FindItem(ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
    2024        8348 :                     if (Found == 0) {
    2025         695 :                         AddMeter(state, ResourceType + ":SpaceType:" + SpaceType, MtrUnits, ResourceType, "", "", "SpaceType");
    2026             :                     }
    2027             :                 }
    2028             :             }
    2029             :         }
    2030             : 
    2031             :         //!!! EndUse Meters
    2032             :         {
    2033      112124 :             auto const endUseMeter(uppercased(EndUse));
    2034             : 
    2035       56062 :             if (endUseMeter.empty()) {
    2036             : 
    2037       56048 :             } else if (endUseMeter == "INTERIOR LIGHTS" || endUseMeter == "INTERIORLIGHTS") {
    2038        4051 :                 EndUse = "InteriorLights";
    2039             : 
    2040       51997 :             } else if (endUseMeter == "EXTERIOR LIGHTS" || endUseMeter == "EXTERIORLIGHTS") {
    2041         182 :                 EndUse = "ExteriorLights";
    2042             : 
    2043       51815 :             } else if (endUseMeter == "HEATING" || endUseMeter == "HTG") {
    2044        9368 :                 EndUse = "Heating";
    2045             : 
    2046       42447 :             } else if (endUseMeter == "HEATPRODUCED") {
    2047          29 :                 EndUse = "HeatProduced";
    2048             : 
    2049       42418 :             } else if (endUseMeter == "COOLING" || endUseMeter == "CLG") {
    2050        7782 :                 EndUse = "Cooling";
    2051             : 
    2052       34636 :             } else if (endUseMeter == "DOMESTICHOTWATER" || endUseMeter == "DHW" || endUseMeter == "DOMESTIC HOT WATER") {
    2053        1218 :                 EndUse = "WaterSystems";
    2054             : 
    2055       33418 :             } else if (endUseMeter == "COGEN" || endUseMeter == "COGENERATION") {
    2056        2175 :                 EndUse = "Cogeneration";
    2057             : 
    2058       31243 :             } else if (endUseMeter == "INTERIOREQUIPMENT" || endUseMeter == "INTERIOR EQUIPMENT") {
    2059        4297 :                 EndUse = "InteriorEquipment";
    2060             : 
    2061       53821 :             } else if (endUseMeter == "EXTERIOREQUIPMENT" || endUseMeter == "EXTERIOR EQUIPMENT" || endUseMeter == "EXT EQ" ||
    2062       26875 :                        endUseMeter == "EXTERIOREQ") {
    2063          71 :                 EndUse = "ExteriorEquipment";
    2064             : 
    2065       26875 :             } else if (endUseMeter == "EXTERIOR:WATEREQUIPMENT") {
    2066           0 :                 EndUse = "ExteriorEquipment";
    2067             : 
    2068       26875 :             } else if (endUseMeter == "PURCHASEDHOTWATER" || endUseMeter == "DISTRICTHOTWATER" || endUseMeter == "PURCHASED HEATING") {
    2069           0 :                 EndUse = "DistrictHotWater";
    2070             : 
    2071      107500 :             } else if (endUseMeter == "PURCHASEDCOLDWATER" || endUseMeter == "DISTRICTCHILLEDWATER" || endUseMeter == "PURCHASEDCHILLEDWATER" ||
    2072       80625 :                        endUseMeter == "PURCHASED COLD WATER" || endUseMeter == "PURCHASED COOLING") {
    2073           0 :                 EndUse = "DistrictChilledWater";
    2074             : 
    2075       26875 :             } else if (endUseMeter == "FANS" || endUseMeter == "FAN") {
    2076        2288 :                 EndUse = "Fans";
    2077             : 
    2078       41944 :             } else if (endUseMeter == "HEATINGCOILS" || endUseMeter == "HEATINGCOIL" || endUseMeter == "HEATING COILS" ||
    2079       17357 :                        endUseMeter == "HEATING COIL") {
    2080        7230 :                 EndUse = "HeatingCoils";
    2081             : 
    2082       32191 :             } else if (endUseMeter == "COOLINGCOILS" || endUseMeter == "COOLINGCOIL" || endUseMeter == "COOLING COILS" ||
    2083       14834 :                        endUseMeter == "COOLING COIL") {
    2084        2523 :                 EndUse = "CoolingCoils";
    2085             : 
    2086       14834 :             } else if (endUseMeter == "PUMPS" || endUseMeter == "PUMP") {
    2087        1154 :                 EndUse = "Pumps";
    2088             : 
    2089       13680 :             } else if (endUseMeter == "FREECOOLING" || endUseMeter == "FREE COOLING") {
    2090           3 :                 EndUse = "Freecooling";
    2091             : 
    2092       13677 :             } else if (endUseMeter == "LOOPTOLOOP") {
    2093          22 :                 EndUse = "LoopToLoop";
    2094             : 
    2095       13655 :             } else if (endUseMeter == "CHILLERS" || endUseMeter == "CHILLER") {
    2096         424 :                 EndUse = "Chillers";
    2097             : 
    2098       13231 :             } else if (endUseMeter == "BOILERS" || endUseMeter == "BOILER") {
    2099         209 :                 EndUse = "Boilers";
    2100             : 
    2101       13022 :             } else if (endUseMeter == "BASEBOARD" || endUseMeter == "BASEBOARDS") {
    2102         151 :                 EndUse = "Baseboard";
    2103             : 
    2104       12871 :             } else if (endUseMeter == "COOLINGPANEL" || endUseMeter == "COOLINGPANELS") {
    2105           8 :                 EndUse = "CoolingPanel";
    2106             : 
    2107       12863 :             } else if (endUseMeter == "HEATREJECTION" || endUseMeter == "HEAT REJECTION") {
    2108        1247 :                 EndUse = "HeatRejection";
    2109             : 
    2110       11616 :             } else if (endUseMeter == "HUMIDIFIER" || endUseMeter == "HUMIDIFIERS") {
    2111         109 :                 EndUse = "Humidifier";
    2112             : 
    2113       11507 :             } else if (endUseMeter == "HEATRECOVERY" || endUseMeter == "HEAT RECOVERY") {
    2114         192 :                 EndUse = "HeatRecovery";
    2115             : 
    2116       11315 :             } else if (endUseMeter == "PHOTOVOLTAICS" || endUseMeter == "PV" || endUseMeter == "PHOTOVOLTAIC") {
    2117          51 :                 EndUse = "Photovoltaic";
    2118             : 
    2119       11264 :             } else if (endUseMeter == "WINDTURBINES" || endUseMeter == "WT" || endUseMeter == "WINDTURBINE") {
    2120           3 :                 EndUse = "WindTurbine";
    2121             : 
    2122       11261 :             } else if (endUseMeter == "ELECTRICSTORAGE") {
    2123          16 :                 EndUse = "ElectricStorage";
    2124             : 
    2125       11245 :             } else if (endUseMeter == "POWERCONVERSION") {
    2126             : 
    2127          16 :                 EndUse = "PowerConversion";
    2128             : 
    2129       22300 :             } else if (endUseMeter == "HEAT RECOVERY FOR COOLING" || endUseMeter == "HEATRECOVERYFORCOOLING" ||
    2130       11071 :                        endUseMeter == "HEATRECOVERYCOOLING") {
    2131         158 :                 EndUse = "HeatRecoveryForCooling";
    2132             : 
    2133       21984 :             } else if (endUseMeter == "HEAT RECOVERY FOR HEATING" || endUseMeter == "HEATRECOVERYFORHEATING" ||
    2134       10913 :                        endUseMeter == "HEATRECOVERYHEATING") {
    2135         158 :                 EndUse = "HeatRecoveryForHeating";
    2136             : 
    2137       10913 :             } else if (endUseMeter == "ELECTRICITYEMISSIONS") {
    2138        1411 :                 EndUse = "ElectricityEmissions";
    2139             : 
    2140        9502 :             } else if (endUseMeter == "PURCHASEDELECTRICITYEMISSIONS") {
    2141          83 :                 EndUse = "PurchasedElectricityEmissions";
    2142             : 
    2143        9419 :             } else if (endUseMeter == "SOLDELECTRICITYEMISSIONS") {
    2144          83 :                 EndUse = "SoldElectricityEmissions";
    2145             : 
    2146        9336 :             } else if (endUseMeter == "NATURALGASEMISSIONS") {
    2147        1292 :                 EndUse = "NaturalGasEmissions";
    2148             : 
    2149        8044 :             } else if (endUseMeter == "FUELOILNO1EMISSIONS") {
    2150         357 :                 EndUse = "FuelOilNo1Emissions";
    2151             : 
    2152        7687 :             } else if (endUseMeter == "FUELOILNO2EMISSIONS") {
    2153           0 :                 EndUse = "FuelOilNo2Emissions";
    2154             : 
    2155        7687 :             } else if (endUseMeter == "COALEMISSIONS") {
    2156           0 :                 EndUse = "CoalEmissions";
    2157             : 
    2158        7687 :             } else if (endUseMeter == "GASOLINEEMISSIONS") {
    2159           0 :                 EndUse = "GasolineEmissions";
    2160             : 
    2161        7687 :             } else if (endUseMeter == "PROPANEEMISSIONS") {
    2162         357 :                 EndUse = "PropaneEmissions";
    2163             : 
    2164        7330 :             } else if (endUseMeter == "DIESELEMISSIONS") {
    2165          34 :                 EndUse = "DieselEmissions";
    2166             : 
    2167        7296 :             } else if (endUseMeter == "OTHERFUEL1EMISSIONS") {
    2168          17 :                 EndUse = "OtherFuel1Emissions";
    2169             : 
    2170        7279 :             } else if (endUseMeter == "OTHERFUEL2EMISSIONS") {
    2171           0 :                 EndUse = "OtherFuel2Emissions";
    2172             : 
    2173        7279 :             } else if (endUseMeter == "CARBONEQUIVALENTEMISSIONS") {
    2174        2307 :                 EndUse = "CarbonEquivalentEmissions";
    2175             : 
    2176        4972 :             } else if (endUseMeter == "REFRIGERATION") {
    2177        1386 :                 EndUse = "Refrigeration";
    2178             : 
    2179        3586 :             } else if (endUseMeter == "COLDSTORAGECHARGE") {
    2180           0 :                 EndUse = "ColdStorageCharge";
    2181             : 
    2182        3586 :             } else if (endUseMeter == "COLDSTORAGEDISCHARGE") {
    2183           0 :                 EndUse = "ColdStorageDischarge";
    2184             : 
    2185        3586 :             } else if (endUseMeter == "WATERSYSTEMS" || endUseMeter == "WATERSYSTEM" || endUseMeter == "Water System") {
    2186        3582 :                 EndUse = "WaterSystems";
    2187             : 
    2188           4 :             } else if (endUseMeter == "RAINWATER") {
    2189           2 :                 EndUse = "Rainwater";
    2190             : 
    2191           2 :             } else if (endUseMeter == "CONDENSATE") {
    2192           0 :                 EndUse = "Condensate";
    2193             : 
    2194           2 :             } else if (endUseMeter == "WELLWATER") {
    2195           2 :                 EndUse = "Wellwater";
    2196             : 
    2197           0 :             } else if (endUseMeter == "MAINSWATER" || endUseMeter == "PURCHASEDWATER") {
    2198           0 :                 EndUse = "MainsWater";
    2199             : 
    2200             :             } else {
    2201           0 :                 ShowSevereError(state, "Illegal EndUse (for Meters) Entered=" + EndUse);
    2202           0 :                 LocalErrorsFound = true;
    2203             :             }
    2204             :         }
    2205             : 
    2206             :         //!! Following if we do EndUse by ResourceType
    2207       56062 :         if (!LocalErrorsFound && !EndUse.empty()) {
    2208       56048 :             Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType, op->EnergyMeters);
    2209       56048 :             if (Found == 0) AddMeter(state, EndUse + ':' + ResourceType, MtrUnits, ResourceType, EndUse, "", "");
    2210             : 
    2211       56048 :             if (Group == "Building") { // Match to Zone and Space
    2212       19144 :                 if (!ZoneName.empty()) {
    2213       18825 :                     Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
    2214       18825 :                     if (Found == 0) {
    2215       17872 :                         AddMeter(state, EndUse + ':' + ResourceType + ":Zone:" + ZoneName, MtrUnits, ResourceType, EndUse, "", "Zone");
    2216             :                     }
    2217             :                 }
    2218       19144 :                 if (!SpaceType.empty()) {
    2219        8348 :                     Found = UtilityRoutines::FindItem(EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
    2220        8348 :                     if (Found == 0) {
    2221        1323 :                         AddMeter(state, EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, MtrUnits, ResourceType, EndUse, "", "SpaceType");
    2222             :                     }
    2223             :                 }
    2224             :             }
    2225          14 :         } else if (LocalErrorsFound) {
    2226           0 :             ErrorsFound = true;
    2227             :         }
    2228             : 
    2229             :         // End-Use Subcategories
    2230       56062 :         if (!LocalErrorsFound && !EndUseSub.empty()) {
    2231       39049 :             MeterName = EndUseSub + ':' + EndUse + ':' + ResourceType;
    2232       39049 :             Found = UtilityRoutines::FindItem(MeterName, op->EnergyMeters);
    2233       39049 :             if (Found == 0) AddMeter(state, MeterName, MtrUnits, ResourceType, EndUse, EndUseSub, "");
    2234             : 
    2235       39049 :             if (Group == "Building") { // Match to Zone and Space
    2236       19144 :                 if (!ZoneName.empty()) {
    2237       18825 :                     Found = UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType + ":Zone:" + ZoneName, op->EnergyMeters);
    2238       18825 :                     if (Found == 0) {
    2239       54366 :                         AddMeter(state,
    2240       36244 :                                  EndUseSub + ':' + EndUse + ':' + ResourceType + ":Zone:" + ZoneName,
    2241             :                                  MtrUnits,
    2242             :                                  ResourceType,
    2243             :                                  EndUse,
    2244             :                                  EndUseSub,
    2245             :                                  "Zone");
    2246             :                     }
    2247             :                 }
    2248       19144 :                 if (!SpaceType.empty()) {
    2249        8348 :                     Found = UtilityRoutines::FindItem(EndUseSub + ':' + EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType, op->EnergyMeters);
    2250        8348 :                     if (Found == 0) {
    2251        4473 :                         AddMeter(state,
    2252        2982 :                                  EndUseSub + ':' + EndUse + ':' + ResourceType + ":SpaceType:" + SpaceType,
    2253             :                                  MtrUnits,
    2254             :                                  ResourceType,
    2255             :                                  EndUse,
    2256             :                                  EndUseSub,
    2257             :                                  "SpaceType");
    2258             :                     }
    2259             :                 }
    2260             :             }
    2261       17013 :         } else if (LocalErrorsFound) {
    2262           0 :             ErrorsFound = true;
    2263             :         }
    2264       56062 :     }
    2265             : 
    2266       93065 :     void DetermineMeterIPUnits(EnergyPlusData &state,
    2267             :                                OutputProcessor::RT_IPUnits &CodeForIPUnits, // Output Code for IP Units
    2268             :                                std::string const &ResourceType,             // Resource Type
    2269             :                                OutputProcessor::Unit const MtrUnits,        // Meter units
    2270             :                                bool &ErrorsFound                            // true if errors found during subroutine
    2271             :     )
    2272             :     {
    2273             : 
    2274             :         // SUBROUTINE INFORMATION:
    2275             :         //       AUTHOR         Linda Lawrie
    2276             :         //       DATE WRITTEN   January 2012
    2277             :         //       MODIFIED       September 2012; made into subroutine
    2278             :         //       RE-ENGINEERED  na
    2279             : 
    2280             :         // PURPOSE OF THIS SUBROUTINE:
    2281             :         // In order to set up tabular reports for IP units, need to search on same strings
    2282             :         // that tabular reports does for IP conversion.
    2283             : 
    2284             :         // REFERENCES:
    2285             :         // OutputReportTabular looks for:
    2286             :         // CONSUMP - not used in meters
    2287             :         // ELEC - Electricity (kWH)
    2288             :         // GAS - Gas (therm)
    2289             :         // COOL - Cooling (ton)
    2290             :         // and we need to add WATER (for m3/gal, etc)
    2291             : 
    2292             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2293      186130 :         std::string UC_ResourceType;
    2294             : 
    2295       93065 :         ErrorsFound = false;
    2296       93065 :         UC_ResourceType = UtilityRoutines::MakeUPPERCase(ResourceType);
    2297             : 
    2298       93065 :         CodeForIPUnits = RT_IPUnits::OtherJ;
    2299       93065 :         if (has(UC_ResourceType, "ELEC")) {
    2300       43259 :             CodeForIPUnits = RT_IPUnits::Electricity;
    2301       49806 :         } else if (has(UC_ResourceType, "GAS")) {
    2302        2489 :             CodeForIPUnits = RT_IPUnits::Gas;
    2303       47317 :         } else if (has(UC_ResourceType, "COOL")) {
    2304        1963 :             CodeForIPUnits = RT_IPUnits::Cooling;
    2305             :         }
    2306       93065 :         if (MtrUnits == OutputProcessor::Unit::m3 && has(UC_ResourceType, "WATER")) {
    2307        3421 :             CodeForIPUnits = RT_IPUnits::Water;
    2308       89644 :         } else if (MtrUnits == OutputProcessor::Unit::m3) {
    2309         288 :             CodeForIPUnits = RT_IPUnits::OtherM3;
    2310             :         }
    2311       93065 :         if (MtrUnits == OutputProcessor::Unit::kg) {
    2312        5570 :             CodeForIPUnits = RT_IPUnits::OtherKG;
    2313             :         }
    2314       93065 :         if (MtrUnits == OutputProcessor::Unit::L) {
    2315         288 :             CodeForIPUnits = RT_IPUnits::OtherL;
    2316             :         }
    2317             :         //  write(outputfiledebug,*) 'resourcetype=',TRIM(resourcetype)
    2318             :         //  write(outputfiledebug,*) 'ipunits type=',CodeForIPUnits
    2319       93065 :         if (!(MtrUnits == OutputProcessor::Unit::kg) && !(MtrUnits == OutputProcessor::Unit::J) && !(MtrUnits == OutputProcessor::Unit::m3) &&
    2320             :             !(MtrUnits == OutputProcessor::Unit::L)) {
    2321           3 :             ShowWarningError(state,
    2322           2 :                              "DetermineMeterIPUnits: Meter units not recognized for IP Units conversion=[" + unitEnumToString(MtrUnits) + "].");
    2323           1 :             ErrorsFound = true;
    2324             :         }
    2325       93065 :     }
    2326             : 
    2327      299088 :     void UpdateMeters(EnergyPlusData &state, int const TimeStamp) // Current TimeStamp (for max/min)
    2328             :     {
    2329             : 
    2330             :         // SUBROUTINE INFORMATION:
    2331             :         //       AUTHOR         Linda Lawrie
    2332             :         //       DATE WRITTEN   April 2001
    2333             :         //       MODIFIED       na
    2334             :         //       RE-ENGINEERED  na
    2335             : 
    2336             :         // PURPOSE OF THIS SUBROUTINE:
    2337             :         // This subroutine updates the meters with the current time step value
    2338             :         // for each meter.  Also, sets min/max values for hourly...run period reporting.
    2339             : 
    2340             :         // METHODOLOGY EMPLOYED:
    2341             :         // Goes thru the number of meters, setting min/max as appropriate.  Uses timestamp
    2342             :         // from calling program.
    2343             : 
    2344             :         // REFERENCES:
    2345             :         // na
    2346             : 
    2347             :         // USE STATEMENTS:
    2348             :         // na
    2349             : 
    2350             :         // Locals
    2351             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    2352             : 
    2353             :         // SUBROUTINE PARAMETER DEFINITIONS:
    2354             :         // na
    2355             : 
    2356             :         // INTERFACE BLOCK SPECIFICATIONS:
    2357             :         // na
    2358             : 
    2359             :         // DERIVED TYPE DEFINITIONS:
    2360             :         // na
    2361             : 
    2362             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2363      299088 :         auto &op(state.dataOutputProcessor);
    2364             : 
    2365      299088 :         if (!op->MeterValue.allocated()) {
    2366           0 :             return;
    2367             :         }
    2368             : 
    2369    36180192 :         for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
    2370    35881104 :             if (op->EnergyMeters(Meter).TypeOfMeter != MtrType::CustomDec && op->EnergyMeters(Meter).TypeOfMeter != MtrType::CustomDiff) {
    2371    35804160 :                 op->EnergyMeters(Meter).TSValue += op->MeterValue(Meter);
    2372             :             } else {
    2373       76944 :                 op->EnergyMeters(Meter).TSValue = op->EnergyMeters(op->EnergyMeters(Meter).SourceMeter).TSValue - op->MeterValue(Meter);
    2374             :             }
    2375    35881104 :             op->EnergyMeters(Meter).HRValue += op->EnergyMeters(Meter).TSValue;
    2376    35881104 :             op->EnergyMeters(Meter).DYValue += op->EnergyMeters(Meter).TSValue;
    2377    35881104 :             op->EnergyMeters(Meter).MNValue += op->EnergyMeters(Meter).TSValue;
    2378    35881104 :             op->EnergyMeters(Meter).YRValue += op->EnergyMeters(Meter).TSValue;
    2379    35881104 :             op->EnergyMeters(Meter).SMValue += op->EnergyMeters(Meter).TSValue;
    2380    35881104 :             if (op->isFinalYear) op->EnergyMeters(Meter).FinYrSMValue += op->EnergyMeters(Meter).TSValue;
    2381             :         }
    2382             :         // Set Max
    2383    36180192 :         for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
    2384             :             // Todo - HRMinVal, HRMaxVal not used
    2385    69557496 :             if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).DYMaxVal) {
    2386     2204712 :                 op->EnergyMeters(Meter).DYMaxVal = op->EnergyMeters(Meter).TSValue;
    2387     2204712 :                 op->EnergyMeters(Meter).DYMaxValDate = TimeStamp;
    2388             :             } else {
    2389    33676392 :                 continue; // Not max val of month or year, if not max of day so far
    2390             :             }
    2391     2204712 :             if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).MNMaxVal) {
    2392     2204712 :                 op->EnergyMeters(Meter).MNMaxVal = op->EnergyMeters(Meter).TSValue;
    2393     2204712 :                 op->EnergyMeters(Meter).MNMaxValDate = TimeStamp;
    2394             :             } else {
    2395           0 :                 continue;
    2396             :             }
    2397     2204712 :             if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).YRMaxVal) {
    2398     2204712 :                 op->EnergyMeters(Meter).YRMaxVal = op->EnergyMeters(Meter).TSValue;
    2399     2204712 :                 op->EnergyMeters(Meter).YRMaxValDate = TimeStamp;
    2400             :             }
    2401     2204712 :             if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).SMMaxVal) {
    2402     2204712 :                 op->EnergyMeters(Meter).SMMaxVal = op->EnergyMeters(Meter).TSValue;
    2403     2204712 :                 op->EnergyMeters(Meter).SMMaxValDate = TimeStamp;
    2404             :             }
    2405     2204712 :             if (op->isFinalYear) {
    2406     2163204 :                 if (op->EnergyMeters(Meter).TSValue > op->EnergyMeters(Meter).FinYrSMMaxVal) {
    2407     2163204 :                     op->EnergyMeters(Meter).FinYrSMMaxVal = op->EnergyMeters(Meter).TSValue;
    2408     2163204 :                     op->EnergyMeters(Meter).FinYrSMMaxValDate = TimeStamp;
    2409             :                 }
    2410             :             }
    2411             :         }
    2412             :         // Set Min
    2413    36180192 :         for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
    2414    70642911 :             if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).DYMinVal) {
    2415     1119297 :                 op->EnergyMeters(Meter).DYMinVal = op->EnergyMeters(Meter).TSValue;
    2416     1119297 :                 op->EnergyMeters(Meter).DYMinValDate = TimeStamp;
    2417             :             } else {
    2418    34761807 :                 continue;
    2419             :             }
    2420     1119297 :             if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).MNMinVal) {
    2421     1119297 :                 op->EnergyMeters(Meter).MNMinVal = op->EnergyMeters(Meter).TSValue;
    2422     1119297 :                 op->EnergyMeters(Meter).MNMinValDate = TimeStamp;
    2423             :             } else {
    2424           0 :                 continue;
    2425             :             }
    2426     1119297 :             if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).YRMinVal) {
    2427     1119297 :                 op->EnergyMeters(Meter).YRMinVal = op->EnergyMeters(Meter).TSValue;
    2428     1119297 :                 op->EnergyMeters(Meter).YRMinValDate = TimeStamp;
    2429             :             }
    2430     1119297 :             if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).SMMinVal) {
    2431     1119297 :                 op->EnergyMeters(Meter).SMMinVal = op->EnergyMeters(Meter).TSValue;
    2432     1119297 :                 op->EnergyMeters(Meter).SMMinValDate = TimeStamp;
    2433             :             }
    2434     1119297 :             if (op->isFinalYear) {
    2435     1110377 :                 if (op->EnergyMeters(Meter).TSValue < op->EnergyMeters(Meter).FinYrSMMinVal) {
    2436     1110377 :                     op->EnergyMeters(Meter).FinYrSMMinVal = op->EnergyMeters(Meter).TSValue;
    2437     1110377 :                     op->EnergyMeters(Meter).FinYrSMMinValDate = TimeStamp;
    2438             :                 }
    2439             :             }
    2440             :         }
    2441    36180192 :         for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
    2442    35881104 :             op->MeterValue(Meter) = 0.0; // Ready for next update
    2443             :         }
    2444             :     }
    2445             : 
    2446        1613 :     void ResetAccumulationWhenWarmupComplete(EnergyPlusData &state)
    2447             :     {
    2448             :         // SUBROUTINE INFORMATION:
    2449             :         //       AUTHOR         Jason Glazer
    2450             :         //       DATE WRITTEN   June 2015
    2451             :         //       MODIFIED       na
    2452             :         //       RE-ENGINEERED  na
    2453             : 
    2454             :         // PURPOSE OF THIS SUBROUTINE:
    2455             :         // Resets the accumulating meter values. Needed after warmup period is over to
    2456             :         // reset the totals on meters so that they are not accumulated over the warmup period
    2457             : 
    2458             :         // METHODOLOGY EMPLOYED:
    2459             :         // Cycle through the meters and reset all accumulating values
    2460             : 
    2461             :         // REFERENCES:
    2462             :         // na
    2463             : 
    2464             :         // USE STATEMENTS:
    2465             :         // na
    2466             : 
    2467             :         // Locals
    2468             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    2469             : 
    2470             :         // SUBROUTINE PARAMETER DEFINITIONS:
    2471             :         // na
    2472             : 
    2473             :         // INTERFACE BLOCK SPECIFICATIONS:
    2474             :         // na
    2475             : 
    2476             :         // DERIVED TYPE DEFINITIONS:
    2477             :         // na
    2478             : 
    2479             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2480             :         int Meter; // Loop Control
    2481             :         int Loop;  // Loop Variable
    2482        1613 :         auto &op(state.dataOutputProcessor);
    2483             : 
    2484      196433 :         for (Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
    2485      194820 :             op->EnergyMeters(Meter).HRValue = 0.0;
    2486             : 
    2487      194820 :             op->EnergyMeters(Meter).DYValue = 0.0;
    2488      194820 :             op->EnergyMeters(Meter).DYMaxVal = MaxSetValue;
    2489      194820 :             op->EnergyMeters(Meter).DYMaxValDate = 0;
    2490      194820 :             op->EnergyMeters(Meter).DYMinVal = MinSetValue;
    2491      194820 :             op->EnergyMeters(Meter).DYMinValDate = 0;
    2492             : 
    2493      194820 :             op->EnergyMeters(Meter).MNValue = 0.0;
    2494      194820 :             op->EnergyMeters(Meter).MNMaxVal = MaxSetValue;
    2495      194820 :             op->EnergyMeters(Meter).MNMaxValDate = 0;
    2496      194820 :             op->EnergyMeters(Meter).MNMinVal = MinSetValue;
    2497      194820 :             op->EnergyMeters(Meter).MNMinValDate = 0;
    2498             : 
    2499      194820 :             op->EnergyMeters(Meter).YRValue = 0.0;
    2500      194820 :             op->EnergyMeters(Meter).YRMaxVal = MaxSetValue;
    2501      194820 :             op->EnergyMeters(Meter).YRMaxValDate = 0;
    2502      194820 :             op->EnergyMeters(Meter).YRMinVal = MinSetValue;
    2503      194820 :             op->EnergyMeters(Meter).YRMinValDate = 0;
    2504             : 
    2505      194820 :             op->EnergyMeters(Meter).SMValue = 0.0;
    2506      194820 :             op->EnergyMeters(Meter).SMMaxVal = MaxSetValue;
    2507      194820 :             op->EnergyMeters(Meter).SMMaxValDate = 0;
    2508      194820 :             op->EnergyMeters(Meter).SMMinVal = MinSetValue;
    2509      194820 :             op->EnergyMeters(Meter).SMMinValDate = 0;
    2510             : 
    2511      194820 :             op->EnergyMeters(Meter).FinYrSMValue = 0.0;
    2512      194820 :             op->EnergyMeters(Meter).FinYrSMMaxVal = MaxSetValue;
    2513      194820 :             op->EnergyMeters(Meter).FinYrSMMaxValDate = 0;
    2514      194820 :             op->EnergyMeters(Meter).FinYrSMMinVal = MinSetValue;
    2515      194820 :             op->EnergyMeters(Meter).FinYrSMMinValDate = 0;
    2516             :         }
    2517             : 
    2518      394673 :         for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    2519      393060 :             auto &rVar(op->RVariableTypes(Loop).VarPtr);
    2520      739588 :             if (rVar.frequency == ReportingFrequency::Monthly || rVar.frequency == ReportingFrequency::Yearly ||
    2521      346528 :                 rVar.frequency == ReportingFrequency::Simulation) {
    2522       47264 :                 rVar.StoreValue = 0.0;
    2523       47264 :                 rVar.NumStored = 0;
    2524             :             }
    2525             :         }
    2526             : 
    2527        9913 :         for (Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    2528        8300 :             auto &iVar(op->IVariableTypes(Loop).VarPtr);
    2529       15876 :             if (iVar.frequency == ReportingFrequency::Monthly || iVar.frequency == ReportingFrequency::Yearly ||
    2530        7576 :                 iVar.frequency == ReportingFrequency::Simulation) {
    2531         724 :                 iVar.StoreValue = 0;
    2532         724 :                 iVar.NumStored = 0;
    2533             :             }
    2534             :         }
    2535        1613 :     }
    2536             : 
    2537      299088 :     void ReportTSMeters(EnergyPlusData &state,
    2538             :                         Real64 const StartMinute, // Start Minute for TimeStep
    2539             :                         Real64 const EndMinute,   // End Minute for TimeStep
    2540             :                         bool &PrintESOTimeStamp,  // True if the ESO Time Stamp also needs to be printed
    2541             :                         bool PrintTimeStampToSQL  // Print Time Stamp to SQL file
    2542             :     )
    2543             :     {
    2544             : 
    2545             :         // SUBROUTINE INFORMATION:
    2546             :         //       AUTHOR         Linda Lawrie
    2547             :         //       DATE WRITTEN   January 2001
    2548             :         //       MODIFIED       na
    2549             :         //       RE-ENGINEERED  na
    2550             : 
    2551             :         // PURPOSE OF THIS SUBROUTINE:
    2552             :         // This subroutine reports on the meters that have been requested for
    2553             :         // reporting on each time step.
    2554             : 
    2555             :         // METHODOLOGY EMPLOYED:
    2556             :         // na
    2557             : 
    2558             :         // REFERENCES:
    2559             :         // na
    2560             : 
    2561             :         // Locals
    2562             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    2563             : 
    2564             :         // SUBROUTINE PARAMETER DEFINITIONS:
    2565             :         // na
    2566             : 
    2567             :         // INTERFACE BLOCK SPECIFICATIONS:
    2568             :         // na
    2569             : 
    2570             :         // DERIVED TYPE DEFINITIONS:
    2571             :         // na
    2572             : 
    2573             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2574             :         int Loop; // Loop Control
    2575             :         bool PrintTimeStamp;
    2576             :         int CurDayType;
    2577      299088 :         auto &op(state.dataOutputProcessor);
    2578             : 
    2579      299088 :         if (!state.dataResultsFramework->resultsFramework->TSMeters.rDataFrameEnabled()) {
    2580      293532 :             state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::TimeStep);
    2581             :         }
    2582             : 
    2583      299088 :         PrintTimeStamp = true;
    2584    36180192 :         for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
    2585    35881104 :             op->EnergyMeters(Loop).CurTSValue = op->EnergyMeters(Loop).TSValue;
    2586    35881104 :             if (!op->EnergyMeters(Loop).RptTS && !op->EnergyMeters(Loop).RptAccTS) continue;
    2587       25824 :             if (PrintTimeStamp) {
    2588        5568 :                 CurDayType = state.dataEnvrn->DayOfWeek;
    2589        5568 :                 if (state.dataEnvrn->HolidayIndex > 0) {
    2590        5568 :                     CurDayType = state.dataEnvrn->HolidayIndex;
    2591             :                 }
    2592       50112 :                 WriteTimeStampFormatData(state,
    2593             :                                          state.files.mtr,
    2594             :                                          ReportingFrequency::EachCall,
    2595        5568 :                                          op->TimeStepStampReportNbr,
    2596        5568 :                                          op->TimeStepStampReportChr,
    2597        5568 :                                          state.dataGlobal->DayOfSimChr,
    2598        5568 :                                          PrintTimeStamp && PrintTimeStampToSQL,
    2599        5568 :                                          state.dataEnvrn->Month,
    2600        5568 :                                          state.dataEnvrn->DayOfMonth,
    2601        5568 :                                          state.dataGlobal->HourOfDay,
    2602             :                                          EndMinute,
    2603             :                                          StartMinute,
    2604        5568 :                                          state.dataEnvrn->DSTIndicator,
    2605        5568 :                                          ScheduleManager::dayTypeNames[CurDayType]);
    2606        5568 :                 if (state.dataResultsFramework->resultsFramework->TSMeters.rDataFrameEnabled()) {
    2607       22272 :                     state.dataResultsFramework->resultsFramework->TSMeters.newRow(
    2608       16704 :                         state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, EndMinute);
    2609             :                 }
    2610        5568 :                 PrintTimeStamp = false;
    2611        5568 :                 PrintTimeStampToSQL = false;
    2612             :             }
    2613             : 
    2614       25824 :             if (PrintESOTimeStamp && !op->EnergyMeters(Loop).RptTSFO && !op->EnergyMeters(Loop).RptAccTSFO) {
    2615           0 :                 CurDayType = state.dataEnvrn->DayOfWeek;
    2616           0 :                 if (state.dataEnvrn->HolidayIndex > 0) {
    2617           0 :                     CurDayType = state.dataEnvrn->HolidayIndex;
    2618             :                 }
    2619           0 :                 WriteTimeStampFormatData(state,
    2620             :                                          state.files.eso,
    2621             :                                          ReportingFrequency::EachCall,
    2622           0 :                                          op->TimeStepStampReportNbr,
    2623           0 :                                          op->TimeStepStampReportChr,
    2624           0 :                                          state.dataGlobal->DayOfSimChr,
    2625           0 :                                          PrintTimeStamp && PrintESOTimeStamp && PrintTimeStampToSQL,
    2626           0 :                                          state.dataEnvrn->Month,
    2627           0 :                                          state.dataEnvrn->DayOfMonth,
    2628           0 :                                          state.dataGlobal->HourOfDay,
    2629             :                                          EndMinute,
    2630             :                                          StartMinute,
    2631           0 :                                          state.dataEnvrn->DSTIndicator,
    2632           0 :                                          ScheduleManager::dayTypeNames[CurDayType]);
    2633           0 :                 PrintESOTimeStamp = false;
    2634             :             }
    2635             : 
    2636       25824 :             if (op->EnergyMeters(Loop).RptTS) {
    2637      206592 :                 WriteReportMeterData(state,
    2638       25824 :                                      op->EnergyMeters(Loop).TSRptNum,
    2639       25824 :                                      op->EnergyMeters(Loop).TSRptNumChr,
    2640       25824 :                                      op->EnergyMeters(Loop).TSValue,
    2641             :                                      ReportingFrequency::TimeStep,
    2642       25824 :                                      state.dataOutputProcessor->rDummy1TS,
    2643       25824 :                                      state.dataOutputProcessor->iDummy1TS,
    2644       25824 :                                      state.dataOutputProcessor->rDummy2TS,
    2645       25824 :                                      state.dataOutputProcessor->iDummy2TS,
    2646       25824 :                                      op->EnergyMeters(Loop).RptTSFO);
    2647       51648 :                 state.dataResultsFramework->resultsFramework->TSMeters.pushVariableValue(op->EnergyMeters(Loop).TSRptNum,
    2648       25824 :                                                                                          op->EnergyMeters(Loop).TSValue);
    2649             :             }
    2650             : 
    2651       25824 :             if (op->EnergyMeters(Loop).RptAccTS) {
    2652           0 :                 WriteCumulativeReportMeterData(state,
    2653           0 :                                                op->EnergyMeters(Loop).TSAccRptNum,
    2654           0 :                                                fmt::to_string(op->EnergyMeters(Loop).TSAccRptNum),
    2655           0 :                                                op->EnergyMeters(Loop).SMValue,
    2656           0 :                                                op->EnergyMeters(Loop).RptAccTSFO);
    2657           0 :                 state.dataResultsFramework->resultsFramework->TSMeters.pushVariableValue(op->EnergyMeters(Loop).TSAccRptNum,
    2658           0 :                                                                                          op->EnergyMeters(Loop).SMValue);
    2659             :             }
    2660             :         }
    2661             : 
    2662      299088 :         if (op->NumEnergyMeters > 0) {
    2663    36180192 :             for (auto &e : op->EnergyMeters)
    2664    35881104 :                 e.TSValue = 0.0;
    2665             :         }
    2666      299088 :     }
    2667             : 
    2668       57768 :     void ReportHRMeters(EnergyPlusData &state, bool PrintTimeStampToSQL // Print Time Stamp to SQL file
    2669             :     )
    2670             :     {
    2671             : 
    2672             :         // SUBROUTINE INFORMATION:
    2673             :         //       AUTHOR         Linda Lawrie
    2674             :         //       DATE WRITTEN   January 2001
    2675             :         //       MODIFIED       na
    2676             :         //       RE-ENGINEERED  na
    2677             : 
    2678             :         // PURPOSE OF THIS SUBROUTINE:
    2679             :         // This subroutine reports on the meters that have been requested for
    2680             :         // reporting on each hour.
    2681             : 
    2682             :         // METHODOLOGY EMPLOYED:
    2683             :         // na
    2684             : 
    2685             :         // REFERENCES:
    2686             :         // na
    2687             : 
    2688             :         // Locals
    2689             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    2690             :         // na
    2691             : 
    2692             :         // SUBROUTINE PARAMETER DEFINITIONS:
    2693             :         // na
    2694             : 
    2695             :         // INTERFACE BLOCK SPECIFICATIONS:
    2696             :         // na
    2697             : 
    2698             :         // DERIVED TYPE DEFINITIONS:
    2699             :         // na
    2700             : 
    2701             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2702             :         int Loop; // Loop Control
    2703             :         bool PrintTimeStamp;
    2704             :         int CurDayType;
    2705       57768 :         auto &op(state.dataOutputProcessor);
    2706             : 
    2707       57768 :         if (!state.dataResultsFramework->resultsFramework->HRMeters.rDataFrameEnabled()) {
    2708       49894 :             state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Hourly);
    2709             :         }
    2710             : 
    2711       57768 :         PrintTimeStamp = true;
    2712     7095912 :         for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
    2713     7038144 :             if (!op->EnergyMeters(Loop).RptHR && !op->EnergyMeters(Loop).RptAccHR) continue;
    2714       39504 :             if (PrintTimeStamp) {
    2715        8016 :                 CurDayType = state.dataEnvrn->DayOfWeek;
    2716        8016 :                 if (state.dataEnvrn->HolidayIndex > 0) {
    2717        7944 :                     CurDayType = state.dataEnvrn->HolidayIndex;
    2718             :                 }
    2719       72144 :                 WriteTimeStampFormatData(state,
    2720             :                                          state.files.mtr,
    2721             :                                          ReportingFrequency::Hourly,
    2722        8016 :                                          op->TimeStepStampReportNbr,
    2723        8016 :                                          op->TimeStepStampReportChr,
    2724        8016 :                                          state.dataGlobal->DayOfSimChr,
    2725        8016 :                                          PrintTimeStamp && PrintTimeStampToSQL,
    2726        8016 :                                          state.dataEnvrn->Month,
    2727        8016 :                                          state.dataEnvrn->DayOfMonth,
    2728        8016 :                                          state.dataGlobal->HourOfDay,
    2729             :                                          _,
    2730             :                                          _,
    2731        8016 :                                          state.dataEnvrn->DSTIndicator,
    2732        8016 :                                          ScheduleManager::dayTypeNames[CurDayType]);
    2733        8016 :                 if (state.dataResultsFramework->resultsFramework->HRMeters.rDataFrameEnabled()) {
    2734       32064 :                     state.dataResultsFramework->resultsFramework->HRMeters.newRow(
    2735       24048 :                         state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    2736             :                 }
    2737        8016 :                 PrintTimeStamp = false;
    2738        8016 :                 PrintTimeStampToSQL = false;
    2739             :             }
    2740             : 
    2741       39504 :             if (op->EnergyMeters(Loop).RptHR) {
    2742      316032 :                 WriteReportMeterData(state,
    2743       39504 :                                      op->EnergyMeters(Loop).HRRptNum,
    2744       39504 :                                      op->EnergyMeters(Loop).HRRptNumChr,
    2745       39504 :                                      op->EnergyMeters(Loop).HRValue,
    2746             :                                      ReportingFrequency::Hourly,
    2747       39504 :                                      state.dataOutputProcessor->rDummy1,
    2748       39504 :                                      state.dataOutputProcessor->iDummy1,
    2749       39504 :                                      state.dataOutputProcessor->rDummy2,
    2750       39504 :                                      state.dataOutputProcessor->iDummy2,
    2751       39504 :                                      op->EnergyMeters(Loop).RptHRFO); // EnergyMeters(Loop)%HRMinVal, EnergyMeters(Loop)%HRMinValDate, & |
    2752             :                                                                       // EnergyMeters(Loop)%HRMaxVal, EnergyMeters(Loop)%HRMaxValDate, &
    2753       79008 :                 state.dataResultsFramework->resultsFramework->HRMeters.pushVariableValue(op->EnergyMeters(Loop).HRRptNum,
    2754       39504 :                                                                                          op->EnergyMeters(Loop).HRValue);
    2755       39504 :                 op->EnergyMeters(Loop).HRValue = 0.0;
    2756             :             }
    2757             : 
    2758       39504 :             if (op->EnergyMeters(Loop).RptAccHR) {
    2759           0 :                 WriteCumulativeReportMeterData(state,
    2760           0 :                                                op->EnergyMeters(Loop).HRAccRptNum,
    2761           0 :                                                fmt::to_string(op->EnergyMeters(Loop).HRAccRptNum),
    2762           0 :                                                op->EnergyMeters(Loop).SMValue,
    2763           0 :                                                op->EnergyMeters(Loop).RptAccHRFO);
    2764           0 :                 state.dataResultsFramework->resultsFramework->HRMeters.pushVariableValue(op->EnergyMeters(Loop).HRAccRptNum,
    2765           0 :                                                                                          op->EnergyMeters(Loop).SMValue);
    2766             :             }
    2767             :         }
    2768       57768 :     }
    2769             : 
    2770        2407 :     void ReportDYMeters(EnergyPlusData &state, bool PrintTimeStampToSQL // Print Time Stamp to SQL file
    2771             :     )
    2772             :     {
    2773             : 
    2774             :         // SUBROUTINE INFORMATION:
    2775             :         //       AUTHOR         Linda Lawrie
    2776             :         //       DATE WRITTEN   January 2001
    2777             :         //       MODIFIED       na
    2778             :         //       RE-ENGINEERED  na
    2779             : 
    2780             :         // PURPOSE OF THIS SUBROUTINE:
    2781             :         // This subroutine reports on the meters that have been requested for
    2782             :         // reporting on each day.
    2783             : 
    2784             :         // METHODOLOGY EMPLOYED:
    2785             :         // na
    2786             : 
    2787             :         // REFERENCES:
    2788             :         // na
    2789             : 
    2790             :         // Locals
    2791             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    2792             :         // na
    2793             : 
    2794             :         // SUBROUTINE PARAMETER DEFINITIONS:
    2795             :         // na
    2796             : 
    2797             :         // INTERFACE BLOCK SPECIFICATIONS:
    2798             :         // na
    2799             : 
    2800             :         // DERIVED TYPE DEFINITIONS:
    2801             :         // na
    2802             : 
    2803             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2804             :         int Loop; // Loop Control
    2805             :         bool PrintTimeStamp;
    2806             :         int CurDayType;
    2807        2407 :         auto &op(state.dataOutputProcessor);
    2808             : 
    2809        2407 :         if (!state.dataResultsFramework->resultsFramework->DYMeters.rVariablesScanned()) {
    2810         769 :             state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Daily);
    2811             :         }
    2812             : 
    2813        2407 :         PrintTimeStamp = true;
    2814      295663 :         for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
    2815      293256 :             if (!op->EnergyMeters(Loop).RptDY && !op->EnergyMeters(Loop).RptAccDY) continue;
    2816         158 :             if (PrintTimeStamp) {
    2817          48 :                 CurDayType = state.dataEnvrn->DayOfWeek;
    2818          48 :                 if (state.dataEnvrn->HolidayIndex > 0) {
    2819          48 :                     CurDayType = state.dataEnvrn->HolidayIndex;
    2820             :                 }
    2821         384 :                 WriteTimeStampFormatData(state,
    2822             :                                          state.files.mtr,
    2823             :                                          ReportingFrequency::Daily,
    2824          48 :                                          op->DailyStampReportNbr,
    2825          48 :                                          op->DailyStampReportChr,
    2826          48 :                                          state.dataGlobal->DayOfSimChr,
    2827          48 :                                          PrintTimeStamp && PrintTimeStampToSQL,
    2828          48 :                                          state.dataEnvrn->Month,
    2829          48 :                                          state.dataEnvrn->DayOfMonth,
    2830             :                                          _,
    2831             :                                          _,
    2832             :                                          _,
    2833          48 :                                          state.dataEnvrn->DSTIndicator,
    2834          48 :                                          ScheduleManager::dayTypeNames[CurDayType]);
    2835          48 :                 if (state.dataResultsFramework->resultsFramework->DYMeters.rDataFrameEnabled()) {
    2836         192 :                     state.dataResultsFramework->resultsFramework->DYMeters.newRow(
    2837         144 :                         state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    2838             :                 }
    2839          48 :                 PrintTimeStamp = false;
    2840          48 :                 PrintTimeStampToSQL = false;
    2841             :             }
    2842             : 
    2843         158 :             if (op->EnergyMeters(Loop).RptDY) {
    2844        1264 :                 WriteReportMeterData(state,
    2845         158 :                                      op->EnergyMeters(Loop).DYRptNum,
    2846         158 :                                      op->EnergyMeters(Loop).DYRptNumChr,
    2847         158 :                                      op->EnergyMeters(Loop).DYValue,
    2848             :                                      ReportingFrequency::Daily,
    2849         158 :                                      op->EnergyMeters(Loop).DYMinVal,
    2850         158 :                                      op->EnergyMeters(Loop).DYMinValDate,
    2851         158 :                                      op->EnergyMeters(Loop).DYMaxVal,
    2852         158 :                                      op->EnergyMeters(Loop).DYMaxValDate,
    2853         158 :                                      op->EnergyMeters(Loop).RptDYFO);
    2854         316 :                 state.dataResultsFramework->resultsFramework->DYMeters.pushVariableValue(op->EnergyMeters(Loop).DYRptNum,
    2855         158 :                                                                                          op->EnergyMeters(Loop).DYValue);
    2856         158 :                 op->EnergyMeters(Loop).DYValue = 0.0;
    2857         158 :                 op->EnergyMeters(Loop).DYMinVal = MinSetValue;
    2858         158 :                 op->EnergyMeters(Loop).DYMaxVal = MaxSetValue;
    2859             :             }
    2860             : 
    2861         158 :             if (op->EnergyMeters(Loop).RptAccDY) {
    2862           0 :                 WriteCumulativeReportMeterData(state,
    2863           0 :                                                op->EnergyMeters(Loop).DYAccRptNum,
    2864           0 :                                                fmt::to_string(op->EnergyMeters(Loop).DYAccRptNum),
    2865           0 :                                                op->EnergyMeters(Loop).SMValue,
    2866           0 :                                                op->EnergyMeters(Loop).RptAccDYFO);
    2867           0 :                 state.dataResultsFramework->resultsFramework->DYMeters.pushVariableValue(op->EnergyMeters(Loop).DYAccRptNum,
    2868           0 :                                                                                          op->EnergyMeters(Loop).SMValue);
    2869             :             }
    2870             :         }
    2871        2407 :     }
    2872             : 
    2873        1669 :     void ReportMNMeters(EnergyPlusData &state, bool PrintTimeStampToSQL // Print Time Stamp to SQL file
    2874             :     )
    2875             :     {
    2876             : 
    2877             :         // SUBROUTINE INFORMATION:
    2878             :         //       AUTHOR         Linda Lawrie
    2879             :         //       DATE WRITTEN   January 2001
    2880             :         //       MODIFIED       na
    2881             :         //       RE-ENGINEERED  na
    2882             : 
    2883             :         // PURPOSE OF THIS SUBROUTINE:
    2884             :         // This subroutine reports on the meters that have been requested for
    2885             :         // reporting on each month.
    2886             : 
    2887             :         // METHODOLOGY EMPLOYED:
    2888             :         // na
    2889             : 
    2890             :         // REFERENCES:
    2891             :         // na
    2892             : 
    2893             :         // Locals
    2894             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    2895             :         // na
    2896             : 
    2897             :         // SUBROUTINE PARAMETER DEFINITIONS:
    2898             :         // na
    2899             : 
    2900             :         // INTERFACE BLOCK SPECIFICATIONS:
    2901             :         // na
    2902             : 
    2903             :         // DERIVED TYPE DEFINITIONS:
    2904             :         // na
    2905             : 
    2906             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2907             :         int Loop; // Loop Control
    2908             :         bool PrintTimeStamp;
    2909        1669 :         auto &op(state.dataOutputProcessor);
    2910             : 
    2911        1669 :         if (!state.dataResultsFramework->resultsFramework->MNMeters.rVariablesScanned()) {
    2912         769 :             state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Monthly);
    2913             :         }
    2914             : 
    2915        1669 :         PrintTimeStamp = true;
    2916      208990 :         for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
    2917      207321 :             if (!op->EnergyMeters(Loop).RptMN && !op->EnergyMeters(Loop).RptAccMN) continue;
    2918       10388 :             if (PrintTimeStamp) {
    2919        7308 :                 WriteTimeStampFormatData(state,
    2920             :                                          state.files.mtr,
    2921             :                                          ReportingFrequency::Monthly,
    2922        1218 :                                          op->MonthlyStampReportNbr,
    2923        1218 :                                          op->MonthlyStampReportChr,
    2924        1218 :                                          state.dataGlobal->DayOfSimChr,
    2925        1218 :                                          PrintTimeStamp && PrintTimeStampToSQL,
    2926        1218 :                                          state.dataEnvrn->Month);
    2927        1218 :                 if (state.dataResultsFramework->resultsFramework->MNMeters.rDataFrameEnabled()) {
    2928        4872 :                     state.dataResultsFramework->resultsFramework->MNMeters.newRow(
    2929        3654 :                         state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    2930             :                 }
    2931        1218 :                 PrintTimeStamp = false;
    2932        1218 :                 PrintTimeStampToSQL = false;
    2933             :             }
    2934             : 
    2935       10388 :             if (op->EnergyMeters(Loop).RptMN) {
    2936       83104 :                 WriteReportMeterData(state,
    2937       10388 :                                      op->EnergyMeters(Loop).MNRptNum,
    2938       10388 :                                      op->EnergyMeters(Loop).MNRptNumChr,
    2939       10388 :                                      op->EnergyMeters(Loop).MNValue,
    2940             :                                      ReportingFrequency::Monthly,
    2941       10388 :                                      op->EnergyMeters(Loop).MNMinVal,
    2942       10388 :                                      op->EnergyMeters(Loop).MNMinValDate,
    2943       10388 :                                      op->EnergyMeters(Loop).MNMaxVal,
    2944       10388 :                                      op->EnergyMeters(Loop).MNMaxValDate,
    2945       10388 :                                      op->EnergyMeters(Loop).RptMNFO);
    2946       20776 :                 state.dataResultsFramework->resultsFramework->MNMeters.pushVariableValue(op->EnergyMeters(Loop).MNRptNum,
    2947       10388 :                                                                                          op->EnergyMeters(Loop).MNValue);
    2948       10388 :                 op->EnergyMeters(Loop).MNValue = 0.0;
    2949       10388 :                 op->EnergyMeters(Loop).MNMinVal = MinSetValue;
    2950       10388 :                 op->EnergyMeters(Loop).MNMaxVal = MaxSetValue;
    2951             :             }
    2952             : 
    2953       10388 :             if (op->EnergyMeters(Loop).RptAccMN) {
    2954          30 :                 WriteCumulativeReportMeterData(state,
    2955          10 :                                                op->EnergyMeters(Loop).MNAccRptNum,
    2956          20 :                                                fmt::to_string(op->EnergyMeters(Loop).MNAccRptNum),
    2957          10 :                                                op->EnergyMeters(Loop).SMValue,
    2958          10 :                                                op->EnergyMeters(Loop).RptAccMNFO);
    2959          20 :                 state.dataResultsFramework->resultsFramework->MNMeters.pushVariableValue(op->EnergyMeters(Loop).MNAccRptNum,
    2960          10 :                                                                                          op->EnergyMeters(Loop).SMValue);
    2961             :             }
    2962             :         }
    2963        1669 :     }
    2964             : 
    2965           2 :     void ReportYRMeters(EnergyPlusData &state, bool PrintTimeStampToSQL)
    2966             :     {
    2967             : 
    2968             :         // SUBROUTINE INFORMATION:
    2969             :         //       AUTHOR         Jason DeGraw
    2970             :         //       DATE WRITTEN   January 2018
    2971             :         //       MODIFIED       na
    2972             :         //       RE-ENGINEERED  na
    2973             : 
    2974             :         // PURPOSE OF THIS SUBROUTINE:
    2975             :         // This subroutine reports on the meters that have been requested for
    2976             :         // reporting on each year.
    2977             : 
    2978             :         // METHODOLOGY EMPLOYED:
    2979             :         // na
    2980             : 
    2981             :         // REFERENCES:
    2982             :         // na
    2983             : 
    2984             :         // Locals
    2985             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    2986             :         // na
    2987             : 
    2988             :         // SUBROUTINE PARAMETER DEFINITIONS:
    2989             :         // na
    2990             : 
    2991             :         // INTERFACE BLOCK SPECIFICATIONS:
    2992             :         // na
    2993             : 
    2994             :         // DERIVED TYPE DEFINITIONS:
    2995             :         // na
    2996             : 
    2997             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2998             :         int Loop; // Loop Control
    2999             :         bool PrintTimeStamp;
    3000           2 :         auto &op(state.dataOutputProcessor);
    3001             : 
    3002           2 :         if (!state.dataResultsFramework->resultsFramework->YRMeters.rVariablesScanned()) {
    3003           2 :             state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Yearly);
    3004             :         }
    3005             : 
    3006           2 :         PrintTimeStamp = true;
    3007         236 :         for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
    3008         234 :             if (!op->EnergyMeters(Loop).RptYR && !op->EnergyMeters(Loop).RptAccYR) continue;
    3009           0 :             if (PrintTimeStamp) {
    3010           0 :                 WriteYearlyTimeStamp(
    3011           0 :                     state, state.files.mtr, op->YearlyStampReportChr, state.dataGlobal->CalendarYearChr, PrintTimeStamp && PrintTimeStampToSQL);
    3012           0 :                 if (state.dataResultsFramework->resultsFramework->YRMeters.rDataFrameEnabled()) {
    3013           0 :                     state.dataResultsFramework->resultsFramework->YRMeters.newRow(
    3014           0 :                         state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    3015             :                 }
    3016           0 :                 PrintTimeStamp = false;
    3017           0 :                 PrintTimeStampToSQL = false;
    3018             :             }
    3019             : 
    3020           0 :             if (op->EnergyMeters(Loop).RptYR) {
    3021           0 :                 WriteReportMeterData(state,
    3022           0 :                                      op->EnergyMeters(Loop).YRRptNum,
    3023           0 :                                      op->EnergyMeters(Loop).YRRptNumChr,
    3024           0 :                                      op->EnergyMeters(Loop).YRValue,
    3025             :                                      ReportingFrequency::Yearly,
    3026           0 :                                      op->EnergyMeters(Loop).YRMinVal,
    3027           0 :                                      op->EnergyMeters(Loop).YRMinValDate,
    3028           0 :                                      op->EnergyMeters(Loop).YRMaxVal,
    3029           0 :                                      op->EnergyMeters(Loop).YRMaxValDate,
    3030           0 :                                      op->EnergyMeters(Loop).RptYRFO);
    3031           0 :                 state.dataResultsFramework->resultsFramework->YRMeters.pushVariableValue(op->EnergyMeters(Loop).YRRptNum,
    3032           0 :                                                                                          op->EnergyMeters(Loop).YRValue);
    3033           0 :                 op->EnergyMeters(Loop).YRValue = 0.0;
    3034           0 :                 op->EnergyMeters(Loop).YRMinVal = MinSetValue;
    3035           0 :                 op->EnergyMeters(Loop).YRMaxVal = MaxSetValue;
    3036             :             }
    3037             : 
    3038           0 :             if (op->EnergyMeters(Loop).RptAccYR) {
    3039           0 :                 WriteCumulativeReportMeterData(state,
    3040           0 :                                                op->EnergyMeters(Loop).YRAccRptNum,
    3041           0 :                                                fmt::to_string(op->EnergyMeters(Loop).YRAccRptNum),
    3042           0 :                                                op->EnergyMeters(Loop).YRValue,
    3043           0 :                                                op->EnergyMeters(Loop).RptAccYRFO);
    3044           0 :                 state.dataResultsFramework->resultsFramework->YRMeters.pushVariableValue(op->EnergyMeters(Loop).YRAccRptNum,
    3045           0 :                                                                                          op->EnergyMeters(Loop).SMValue);
    3046             :             }
    3047             :         }
    3048           2 :     }
    3049             : 
    3050        1645 :     void ReportSMMeters(EnergyPlusData &state, bool PrintTimeStampToSQL // Print Time Stamp to SQL file
    3051             :     )
    3052             :     {
    3053             : 
    3054             :         // SUBROUTINE INFORMATION:
    3055             :         //       AUTHOR         Linda Lawrie
    3056             :         //       DATE WRITTEN   January 2001
    3057             :         //       MODIFIED       na
    3058             :         //       RE-ENGINEERED  na
    3059             : 
    3060             :         // PURPOSE OF THIS SUBROUTINE:
    3061             :         // This subroutine reports on the meters that have been requested for
    3062             :         // reporting on each environment/run period.
    3063             : 
    3064             :         // METHODOLOGY EMPLOYED:
    3065             :         // na
    3066             : 
    3067             :         // REFERENCES:
    3068             :         // na
    3069             : 
    3070             :         // Using/Aliasing
    3071             :         // using namespace OutputReportPredefined;
    3072             : 
    3073             :         // Locals
    3074             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    3075             :         // na
    3076             : 
    3077             :         // SUBROUTINE PARAMETER DEFINITIONS:
    3078             : 
    3079             :         // INTERFACE BLOCK SPECIFICATIONS:
    3080             :         // na
    3081             : 
    3082             :         // DERIVED TYPE DEFINITIONS:
    3083             :         // na
    3084             : 
    3085             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3086             :         int Loop; // Loop Control
    3087             :         bool PrintTimeStamp;
    3088        1645 :         auto &op(state.dataOutputProcessor);
    3089             : 
    3090        1645 :         if (!state.dataResultsFramework->resultsFramework->SMMeters.rVariablesScanned()) {
    3091         769 :             state.dataResultsFramework->resultsFramework->initializeMeters(op->EnergyMeters, ReportingFrequency::Simulation);
    3092             :         }
    3093             : 
    3094        1645 :         PrintTimeStamp = true;
    3095      206219 :         for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
    3096      204574 :             op->EnergyMeters(Loop).LastSMValue = op->EnergyMeters(Loop).SMValue;
    3097      204574 :             op->EnergyMeters(Loop).LastSMMinVal = op->EnergyMeters(Loop).SMMinVal;
    3098      204574 :             op->EnergyMeters(Loop).LastSMMinValDate = op->EnergyMeters(Loop).SMMinValDate;
    3099      204574 :             op->EnergyMeters(Loop).LastSMMaxVal = op->EnergyMeters(Loop).SMMaxVal;
    3100      204574 :             op->EnergyMeters(Loop).LastSMMaxValDate = op->EnergyMeters(Loop).SMMaxValDate;
    3101      204574 :             if (!op->EnergyMeters(Loop).RptSM && !op->EnergyMeters(Loop).RptAccSM) continue;
    3102        5836 :             if (PrintTimeStamp) {
    3103        5305 :                 WriteTimeStampFormatData(state,
    3104             :                                          state.files.mtr,
    3105             :                                          ReportingFrequency::Simulation,
    3106        1061 :                                          op->RunPeriodStampReportNbr,
    3107        1061 :                                          op->RunPeriodStampReportChr,
    3108        1061 :                                          state.dataGlobal->DayOfSimChr,
    3109        1061 :                                          PrintTimeStamp && PrintTimeStampToSQL);
    3110        1061 :                 if (state.dataResultsFramework->resultsFramework->SMMeters.rDataFrameEnabled()) {
    3111        4244 :                     state.dataResultsFramework->resultsFramework->SMMeters.newRow(
    3112        3183 :                         state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    3113             :                 }
    3114        1061 :                 PrintTimeStamp = false;
    3115        1061 :                 PrintTimeStampToSQL = false;
    3116             :             }
    3117             : 
    3118        5836 :             if (op->EnergyMeters(Loop).RptSM) {
    3119       46688 :                 WriteReportMeterData(state,
    3120        5836 :                                      op->EnergyMeters(Loop).SMRptNum,
    3121        5836 :                                      op->EnergyMeters(Loop).SMRptNumChr,
    3122        5836 :                                      op->EnergyMeters(Loop).SMValue,
    3123             :                                      ReportingFrequency::Simulation,
    3124        5836 :                                      op->EnergyMeters(Loop).SMMinVal,
    3125        5836 :                                      op->EnergyMeters(Loop).SMMinValDate,
    3126        5836 :                                      op->EnergyMeters(Loop).SMMaxVal,
    3127        5836 :                                      op->EnergyMeters(Loop).SMMaxValDate,
    3128        5836 :                                      op->EnergyMeters(Loop).RptSMFO);
    3129       11672 :                 state.dataResultsFramework->resultsFramework->SMMeters.pushVariableValue(op->EnergyMeters(Loop).SMRptNum,
    3130        5836 :                                                                                          op->EnergyMeters(Loop).SMValue);
    3131             :             }
    3132             : 
    3133        5836 :             if (op->EnergyMeters(Loop).RptAccSM) {
    3134           0 :                 WriteCumulativeReportMeterData(state,
    3135           0 :                                                op->EnergyMeters(Loop).SMAccRptNum,
    3136           0 :                                                fmt::to_string(op->EnergyMeters(Loop).SMAccRptNum),
    3137           0 :                                                op->EnergyMeters(Loop).SMValue,
    3138           0 :                                                op->EnergyMeters(Loop).RptAccSMFO);
    3139           0 :                 state.dataResultsFramework->resultsFramework->SMMeters.pushVariableValue(op->EnergyMeters(Loop).SMAccRptNum,
    3140           0 :                                                                                          op->EnergyMeters(Loop).SMValue);
    3141             :             }
    3142             :         }
    3143             : 
    3144        1645 :         if (op->NumEnergyMeters > 0) {
    3145      206219 :             for (auto &e : op->EnergyMeters) {
    3146      204574 :                 e.SMValue = 0.0;
    3147      204574 :                 e.SMMinVal = MinSetValue;
    3148      204574 :                 e.SMMaxVal = MaxSetValue;
    3149             :             }
    3150             :         }
    3151        1645 :     }
    3152             : 
    3153         769 :     void ReportForTabularReports(EnergyPlusData &state)
    3154             :     {
    3155             : 
    3156             :         // SUBROUTINE INFORMATION:
    3157             :         //       AUTHOR         Linda Lawrie
    3158             :         //       DATE WRITTEN   August 2013
    3159             :         //       MODIFIED       na
    3160             :         //       RE-ENGINEERED  na
    3161             : 
    3162             :         // PURPOSE OF THIS SUBROUTINE:
    3163             :         // This subroutine is called after all the simulation is done and before
    3164             :         // tabular reports in order to reduce the number of calls to the predefined routine
    3165             :         // for SM (Simulation period) meters, the value of the last calculation is stored
    3166             :         // in the data structure.
    3167             : 
    3168             :         // Using/Aliasing
    3169             :         using namespace OutputReportPredefined;
    3170             : 
    3171             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3172             :         int Loop; // Loop Control
    3173         769 :         auto &op(state.dataOutputProcessor);
    3174             : 
    3175       93658 :         for (Loop = 1; Loop <= op->NumEnergyMeters; ++Loop) {
    3176       92889 :             OutputProcessor::RT_IPUnits const RT_forIPUnits(op->EnergyMeters(Loop).RT_forIPUnits);
    3177       92889 :             if (RT_forIPUnits == RT_IPUnits::Electricity) {
    3178      172652 :                 PreDefTableEntry(state,
    3179       43163 :                                  state.dataOutRptPredefined->pdchEMelecannual,
    3180       43163 :                                  op->EnergyMeters(Loop).Name,
    3181       43163 :                                  op->EnergyMeters(Loop).FinYrSMValue * DataGlobalConstants::convertJtoGJ);
    3182      172652 :                 PreDefTableEntry(state,
    3183       43163 :                                  state.dataOutRptPredefined->pdchEMelecminvalue,
    3184       43163 :                                  op->EnergyMeters(Loop).Name,
    3185       43163 :                                  op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
    3186      129489 :                 PreDefTableEntry(state,
    3187       43163 :                                  state.dataOutRptPredefined->pdchEMelecminvaluetime,
    3188       43163 :                                  op->EnergyMeters(Loop).Name,
    3189       86326 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
    3190      172652 :                 PreDefTableEntry(state,
    3191       43163 :                                  state.dataOutRptPredefined->pdchEMelecmaxvalue,
    3192       43163 :                                  op->EnergyMeters(Loop).Name,
    3193       43163 :                                  op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
    3194      129489 :                 PreDefTableEntry(state,
    3195       43163 :                                  state.dataOutRptPredefined->pdchEMelecmaxvaluetime,
    3196       43163 :                                  op->EnergyMeters(Loop).Name,
    3197       86326 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
    3198       49726 :             } else if (RT_forIPUnits == RT_IPUnits::Gas) {
    3199        9956 :                 PreDefTableEntry(state,
    3200        2489 :                                  state.dataOutRptPredefined->pdchEMgasannual,
    3201        2489 :                                  op->EnergyMeters(Loop).Name,
    3202        2489 :                                  op->EnergyMeters(Loop).FinYrSMValue * DataGlobalConstants::convertJtoGJ);
    3203        9956 :                 PreDefTableEntry(state,
    3204        2489 :                                  state.dataOutRptPredefined->pdchEMgasminvalue,
    3205        2489 :                                  op->EnergyMeters(Loop).Name,
    3206        2489 :                                  op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
    3207        7467 :                 PreDefTableEntry(state,
    3208        2489 :                                  state.dataOutRptPredefined->pdchEMgasminvaluetime,
    3209        2489 :                                  op->EnergyMeters(Loop).Name,
    3210        4978 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
    3211        9956 :                 PreDefTableEntry(state,
    3212        2489 :                                  state.dataOutRptPredefined->pdchEMgasmaxvalue,
    3213        2489 :                                  op->EnergyMeters(Loop).Name,
    3214        2489 :                                  op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
    3215        7467 :                 PreDefTableEntry(state,
    3216        2489 :                                  state.dataOutRptPredefined->pdchEMgasmaxvaluetime,
    3217        2489 :                                  op->EnergyMeters(Loop).Name,
    3218        4978 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
    3219       47237 :             } else if (RT_forIPUnits == RT_IPUnits::Cooling) {
    3220        7852 :                 PreDefTableEntry(state,
    3221        1963 :                                  state.dataOutRptPredefined->pdchEMcoolannual,
    3222        1963 :                                  op->EnergyMeters(Loop).Name,
    3223        1963 :                                  op->EnergyMeters(Loop).FinYrSMValue * DataGlobalConstants::convertJtoGJ);
    3224        7852 :                 PreDefTableEntry(state,
    3225        1963 :                                  state.dataOutRptPredefined->pdchEMcoolminvalue,
    3226        1963 :                                  op->EnergyMeters(Loop).Name,
    3227        1963 :                                  op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
    3228        5889 :                 PreDefTableEntry(state,
    3229        1963 :                                  state.dataOutRptPredefined->pdchEMcoolminvaluetime,
    3230        1963 :                                  op->EnergyMeters(Loop).Name,
    3231        3926 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
    3232        7852 :                 PreDefTableEntry(state,
    3233        1963 :                                  state.dataOutRptPredefined->pdchEMcoolmaxvalue,
    3234        1963 :                                  op->EnergyMeters(Loop).Name,
    3235        1963 :                                  op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
    3236        5889 :                 PreDefTableEntry(state,
    3237        1963 :                                  state.dataOutRptPredefined->pdchEMcoolmaxvaluetime,
    3238        1963 :                                  op->EnergyMeters(Loop).Name,
    3239        3926 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
    3240       45274 :             } else if (RT_forIPUnits == RT_IPUnits::Water) {
    3241       13684 :                 PreDefTableEntry(
    3242       10263 :                     state, state.dataOutRptPredefined->pdchEMwaterannual, op->EnergyMeters(Loop).Name, op->EnergyMeters(Loop).FinYrSMValue);
    3243       13684 :                 PreDefTableEntry(state,
    3244        3421 :                                  state.dataOutRptPredefined->pdchEMwaterminvalue,
    3245        3421 :                                  op->EnergyMeters(Loop).Name,
    3246        3421 :                                  op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
    3247       10263 :                 PreDefTableEntry(state,
    3248        3421 :                                  state.dataOutRptPredefined->pdchEMwaterminvaluetime,
    3249        3421 :                                  op->EnergyMeters(Loop).Name,
    3250        6842 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
    3251       13684 :                 PreDefTableEntry(state,
    3252        3421 :                                  state.dataOutRptPredefined->pdchEMwatermaxvalue,
    3253        3421 :                                  op->EnergyMeters(Loop).Name,
    3254        3421 :                                  op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
    3255       10263 :                 PreDefTableEntry(state,
    3256        3421 :                                  state.dataOutRptPredefined->pdchEMwatermaxvaluetime,
    3257        3421 :                                  op->EnergyMeters(Loop).Name,
    3258        6842 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
    3259       41853 :             } else if (RT_forIPUnits == RT_IPUnits::OtherKG) {
    3260       22280 :                 PreDefTableEntry(
    3261       16710 :                     state, state.dataOutRptPredefined->pdchEMotherKGannual, op->EnergyMeters(Loop).Name, op->EnergyMeters(Loop).FinYrSMValue);
    3262       22280 :                 PreDefTableEntry(state,
    3263        5570 :                                  state.dataOutRptPredefined->pdchEMotherKGminvalue,
    3264        5570 :                                  op->EnergyMeters(Loop).Name,
    3265        5570 :                                  op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec,
    3266             :                                  3);
    3267       16710 :                 PreDefTableEntry(state,
    3268        5570 :                                  state.dataOutRptPredefined->pdchEMotherKGminvaluetime,
    3269        5570 :                                  op->EnergyMeters(Loop).Name,
    3270       11140 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
    3271       22280 :                 PreDefTableEntry(state,
    3272        5570 :                                  state.dataOutRptPredefined->pdchEMotherKGmaxvalue,
    3273        5570 :                                  op->EnergyMeters(Loop).Name,
    3274        5570 :                                  op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec,
    3275             :                                  3);
    3276       16710 :                 PreDefTableEntry(state,
    3277        5570 :                                  state.dataOutRptPredefined->pdchEMotherKGmaxvaluetime,
    3278        5570 :                                  op->EnergyMeters(Loop).Name,
    3279       11140 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
    3280       36283 :             } else if (RT_forIPUnits == RT_IPUnits::OtherM3) {
    3281        1152 :                 PreDefTableEntry(
    3282         864 :                     state, state.dataOutRptPredefined->pdchEMotherM3annual, op->EnergyMeters(Loop).Name, op->EnergyMeters(Loop).FinYrSMValue, 3);
    3283        1152 :                 PreDefTableEntry(state,
    3284         288 :                                  state.dataOutRptPredefined->pdchEMotherM3minvalue,
    3285         288 :                                  op->EnergyMeters(Loop).Name,
    3286         288 :                                  op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec,
    3287             :                                  3);
    3288         864 :                 PreDefTableEntry(state,
    3289         288 :                                  state.dataOutRptPredefined->pdchEMotherM3minvaluetime,
    3290         288 :                                  op->EnergyMeters(Loop).Name,
    3291         576 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
    3292        1152 :                 PreDefTableEntry(state,
    3293         288 :                                  state.dataOutRptPredefined->pdchEMotherM3maxvalue,
    3294         288 :                                  op->EnergyMeters(Loop).Name,
    3295         288 :                                  op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec,
    3296             :                                  3);
    3297         864 :                 PreDefTableEntry(state,
    3298         288 :                                  state.dataOutRptPredefined->pdchEMotherM3maxvaluetime,
    3299         288 :                                  op->EnergyMeters(Loop).Name,
    3300         576 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
    3301       35995 :             } else if (RT_forIPUnits == RT_IPUnits::OtherL) {
    3302        1152 :                 PreDefTableEntry(
    3303         864 :                     state, state.dataOutRptPredefined->pdchEMotherLannual, op->EnergyMeters(Loop).Name, op->EnergyMeters(Loop).FinYrSMValue, 3);
    3304        1152 :                 PreDefTableEntry(state,
    3305         288 :                                  state.dataOutRptPredefined->pdchEMotherLminvalue,
    3306         288 :                                  op->EnergyMeters(Loop).Name,
    3307         288 :                                  op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec,
    3308             :                                  3);
    3309         864 :                 PreDefTableEntry(state,
    3310         288 :                                  state.dataOutRptPredefined->pdchEMotherLminvaluetime,
    3311         288 :                                  op->EnergyMeters(Loop).Name,
    3312         576 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
    3313        1152 :                 PreDefTableEntry(state,
    3314         288 :                                  state.dataOutRptPredefined->pdchEMotherLmaxvalue,
    3315         288 :                                  op->EnergyMeters(Loop).Name,
    3316         288 :                                  op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec,
    3317             :                                  3);
    3318         864 :                 PreDefTableEntry(state,
    3319         288 :                                  state.dataOutRptPredefined->pdchEMotherLmaxvaluetime,
    3320         288 :                                  op->EnergyMeters(Loop).Name,
    3321         576 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
    3322             :             } else {
    3323      142828 :                 PreDefTableEntry(state,
    3324       35707 :                                  state.dataOutRptPredefined->pdchEMotherJannual,
    3325       35707 :                                  op->EnergyMeters(Loop).Name,
    3326       35707 :                                  op->EnergyMeters(Loop).FinYrSMValue * DataGlobalConstants::convertJtoGJ);
    3327      142828 :                 PreDefTableEntry(state,
    3328       35707 :                                  state.dataOutRptPredefined->pdchEMotherJminvalue,
    3329       35707 :                                  op->EnergyMeters(Loop).Name,
    3330       35707 :                                  op->EnergyMeters(Loop).FinYrSMMinVal / state.dataGlobal->TimeStepZoneSec);
    3331      107121 :                 PreDefTableEntry(state,
    3332       35707 :                                  state.dataOutRptPredefined->pdchEMotherJminvaluetime,
    3333       35707 :                                  op->EnergyMeters(Loop).Name,
    3334       71414 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMinValDate));
    3335      142828 :                 PreDefTableEntry(state,
    3336       35707 :                                  state.dataOutRptPredefined->pdchEMotherJmaxvalue,
    3337       35707 :                                  op->EnergyMeters(Loop).Name,
    3338       35707 :                                  op->EnergyMeters(Loop).FinYrSMMaxVal / state.dataGlobal->TimeStepZoneSec);
    3339      107121 :                 PreDefTableEntry(state,
    3340       35707 :                                  state.dataOutRptPredefined->pdchEMotherJmaxvaluetime,
    3341       35707 :                                  op->EnergyMeters(Loop).Name,
    3342       71414 :                                  DateToStringWithMonth(op->EnergyMeters(Loop).FinYrSMMaxValDate));
    3343             :             }
    3344             :         }
    3345         769 :     }
    3346             : 
    3347      185778 :     std::string DateToStringWithMonth(int const codedDate) // word containing encoded month, day, hour, minute
    3348             :     {
    3349             :         // SUBROUTINE INFORMATION:
    3350             :         //       AUTHOR         Jason Glazer
    3351             :         //       DATE WRITTEN   August 2003
    3352             :         //       MODIFIED       na
    3353             :         //       RE-ENGINEERED  na
    3354             : 
    3355             :         // PURPOSE OF THIS SUBROUTINE:
    3356             :         //   Convert the coded date format into a usable
    3357             :         //   string
    3358             : 
    3359      185778 :         if (codedDate == 0) return "-";
    3360             : 
    3361             :         static constexpr std::string_view DateFmt("{:02}-{:3}-{:02}:{:02}");
    3362             : 
    3363             :         // ((month*100 + day)*100 + hour)*100 + minute
    3364             :         int Month;  // month in integer format (1-12)
    3365             :         int Day;    // day in integer format (1-31)
    3366             :         int Hour;   // hour in integer format (1-24)
    3367             :         int Minute; // minute in integer format (0:59)
    3368             : 
    3369      185778 :         General::DecodeMonDayHrMin(codedDate, Month, Day, Hour, Minute);
    3370             : 
    3371      185778 :         if (Month < 1 || Month > 12) return "-";
    3372      185778 :         if (Day < 1 || Day > 31) return "-";
    3373      185778 :         if (Hour < 1 || Hour > 24) return "-";
    3374      185778 :         if (Minute < 0 || Minute > 60) return "-";
    3375             : 
    3376      185778 :         --Hour;
    3377      185778 :         if (Minute == 60) {
    3378       24606 :             ++Hour;
    3379       24606 :             Minute = 0;
    3380             :         }
    3381             : 
    3382      371556 :         std::string monthName;
    3383      185778 :         switch (Month) {
    3384        9072 :         case 1:
    3385        9072 :             monthName = "JAN";
    3386        9072 :             break;
    3387          41 :         case 2:
    3388          41 :             monthName = "FEB";
    3389          41 :             break;
    3390          22 :         case 3:
    3391          22 :             monthName = "MAR";
    3392          22 :             break;
    3393         272 :         case 4:
    3394         272 :             monthName = "APR";
    3395         272 :             break;
    3396           0 :         case 5:
    3397           0 :             monthName = "MAY";
    3398           0 :             break;
    3399          37 :         case 6:
    3400          37 :             monthName = "JUN";
    3401          37 :             break;
    3402      174392 :         case 7:
    3403      174392 :             monthName = "JUL";
    3404      174392 :             break;
    3405          24 :         case 8:
    3406          24 :             monthName = "AUG";
    3407          24 :             break;
    3408         880 :         case 9:
    3409         880 :             monthName = "SEP";
    3410         880 :             break;
    3411           3 :         case 10:
    3412           3 :             monthName = "OCT";
    3413           3 :             break;
    3414           0 :         case 11:
    3415           0 :             monthName = "NOV";
    3416           0 :             break;
    3417        1035 :         case 12:
    3418        1035 :             monthName = "DEC";
    3419        1035 :             break;
    3420           0 :         default:
    3421           0 :             assert(false);
    3422             :         }
    3423             : 
    3424      185778 :         return format(DateFmt, Day, monthName, Hour, Minute);
    3425             :     }
    3426             : 
    3427         769 :     void ReportMeterDetails(EnergyPlusData &state)
    3428             :     {
    3429             : 
    3430             :         // SUBROUTINE INFORMATION:
    3431             :         //       AUTHOR         Linda Lawrie
    3432             :         //       DATE WRITTEN   January 2006
    3433             :         //       MODIFIED       na
    3434             :         //       RE-ENGINEERED  na
    3435             : 
    3436             :         // PURPOSE OF THIS SUBROUTINE:
    3437             :         // Writes the meter details report.  This shows which variables are on
    3438             :         // meters as well as the meter contents.
    3439             : 
    3440             :         // METHODOLOGY EMPLOYED:
    3441             :         // na
    3442             : 
    3443             :         // REFERENCES:
    3444             :         // na
    3445             : 
    3446             :         // USE STATEMENTS:
    3447             :         // na
    3448             : 
    3449             :         // Locals
    3450             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    3451             :         // na
    3452             : 
    3453             :         // SUBROUTINE PARAMETER DEFINITIONS:
    3454             :         // na
    3455             : 
    3456             :         // INTERFACE BLOCK SPECIFICATIONS:
    3457             :         // na
    3458             : 
    3459             :         // DERIVED TYPE DEFINITIONS:
    3460             :         // na
    3461             : 
    3462             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3463         769 :         auto &op(state.dataOutputProcessor);
    3464             : 
    3465       56940 :         for (int VarMeter = 1; VarMeter <= op->NumVarMeterArrays; ++VarMeter) {
    3466             : 
    3467      112342 :             const std::string mtrUnitString = unitEnumToStringBrackets(op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).units);
    3468             : 
    3469      112342 :             std::string Multipliers;
    3470       56171 :             const auto ZoneMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneMult;
    3471       56171 :             const auto ZoneListMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneListMult;
    3472             : 
    3473       56171 :             if (ZoneMult > 1 || ZoneListMult > 1) {
    3474        1131 :                 Multipliers = format(" * {}  (Zone Multiplier = {}, Zone List Multiplier = {})", ZoneMult * ZoneListMult, ZoneMult, ZoneListMult);
    3475             :             }
    3476             : 
    3477      168513 :             print(state.files.mtd,
    3478             :                   "\n Meters for {},{}{}{}\n",
    3479       56171 :                   op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ReportIDChr,
    3480       56171 :                   op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarName,
    3481             :                   mtrUnitString,
    3482       56171 :                   Multipliers);
    3483             : 
    3484      338329 :             for (int I = 1; I <= op->VarMeterArrays(VarMeter).NumOnMeters; ++I) {
    3485      282158 :                 print(state.files.mtd, "  OnMeter={}{}\n", op->EnergyMeters(op->VarMeterArrays(VarMeter).OnMeters(I)).Name, mtrUnitString);
    3486             :             }
    3487             : 
    3488       56982 :             for (int I = 1; I <= op->VarMeterArrays(VarMeter).NumOnCustomMeters; ++I) {
    3489        1622 :                 print(
    3490        1622 :                     state.files.mtd, "  OnCustomMeter={}{}\n", op->EnergyMeters(op->VarMeterArrays(VarMeter).OnCustomMeters(I)).Name, mtrUnitString);
    3491             :             }
    3492             :         }
    3493             : 
    3494       93658 :         for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
    3495       92889 :             print(state.files.mtd, "\n For Meter={}{}", op->EnergyMeters(Meter).Name, unitEnumToStringBrackets(op->EnergyMeters(Meter).Units));
    3496       92889 :             if (!op->EnergyMeters(Meter).ResourceType.empty()) {
    3497       92889 :                 print(state.files.mtd, ", ResourceType={}", op->EnergyMeters(Meter).ResourceType);
    3498             :             }
    3499       92889 :             if (!op->EnergyMeters(Meter).EndUse.empty()) {
    3500       66639 :                 print(state.files.mtd, ", EndUse={}", op->EnergyMeters(Meter).EndUse);
    3501             :             }
    3502       92889 :             if (!op->EnergyMeters(Meter).Group.empty()) {
    3503       56608 :                 print(state.files.mtd, ", Group={}", op->EnergyMeters(Meter).Group);
    3504             :             }
    3505       92889 :             print(state.files.mtd, ", contents are:\n");
    3506             : 
    3507       92889 :             bool CustDecWritten = false;
    3508             : 
    3509    20132138 :             for (int VarMeter = 1; VarMeter <= op->NumVarMeterArrays; ++VarMeter) {
    3510    20039249 :                 if (op->EnergyMeters(Meter).TypeOfMeter == MtrType::Normal) {
    3511    20024036 :                     if (any_eq(op->VarMeterArrays(VarMeter).OnMeters, Meter)) {
    3512     2072266 :                         for (int VarMeter1 = 1; VarMeter1 <= op->VarMeterArrays(VarMeter).NumOnMeters; ++VarMeter1) {
    3513     1790108 :                             if (op->VarMeterArrays(VarMeter).OnMeters(VarMeter1) != Meter) continue;
    3514             : 
    3515      564316 :                             std::string Multipliers;
    3516      282158 :                             const auto ZoneMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneMult;
    3517      282158 :                             const auto ZoneListMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneListMult;
    3518             : 
    3519      282158 :                             if (ZoneMult > 1 || ZoneListMult > 1) {
    3520        9540 :                                 Multipliers = format(
    3521       19080 :                                     " * {}  (Zone Multiplier = {}, Zone List Multiplier = {})", ZoneMult * ZoneListMult, ZoneMult, ZoneListMult);
    3522             :                             }
    3523             : 
    3524      282158 :                             print(state.files.mtd, "  {}{}\n", op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarName, Multipliers);
    3525             :                         }
    3526             :                     }
    3527             :                 }
    3528    20039249 :                 if (op->EnergyMeters(Meter).TypeOfMeter != MtrType::Normal) {
    3529       15213 :                     if (op->VarMeterArrays(VarMeter).NumOnCustomMeters > 0) {
    3530        2002 :                         if (any_eq(op->VarMeterArrays(VarMeter).OnCustomMeters, Meter)) {
    3531         811 :                             if (!CustDecWritten && op->EnergyMeters(Meter).TypeOfMeter == MtrType::CustomDec) {
    3532          76 :                                 print(state.files.mtd,
    3533             :                                       " Values for this meter will be Source Meter={}; but will be decremented by:\n",
    3534          76 :                                       op->EnergyMeters(op->EnergyMeters(Meter).SourceMeter).Name);
    3535          38 :                                 CustDecWritten = true;
    3536             :                             }
    3537        2540 :                             for (int VarMeter1 = 1; VarMeter1 <= op->VarMeterArrays(VarMeter).NumOnCustomMeters; ++VarMeter1) {
    3538        1729 :                                 if (op->VarMeterArrays(VarMeter).OnCustomMeters(VarMeter1) != Meter) continue;
    3539             : 
    3540        1622 :                                 std::string Multipliers;
    3541         811 :                                 const auto ZoneMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneMult;
    3542         811 :                                 const auto ZoneListMult = op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarPtr.ZoneListMult;
    3543             : 
    3544         811 :                                 if (ZoneMult > 1 || ZoneListMult > 1) {
    3545          24 :                                     Multipliers = format(
    3546          48 :                                         " * {}  (Zone Multiplier = {}, Zone List Multiplier = {})", ZoneMult * ZoneListMult, ZoneMult, ZoneListMult);
    3547             :                                 }
    3548             : 
    3549         811 :                                 print(state.files.mtd, "  {}{}\n", op->RVariableTypes(op->VarMeterArrays(VarMeter).RepVariable).VarName, Multipliers);
    3550             :                             }
    3551             :                         }
    3552             :                     }
    3553             :                 }
    3554             :             }
    3555             :         }
    3556         769 :     }
    3557             : 
    3558             :     // *****************************************************************************
    3559             :     // End of routines for Energy Meters implementation in EnergyPlus.
    3560             :     // *****************************************************************************
    3561             : 
    3562       39049 :     void addEndUseSubcategory(EnergyPlusData &state, std::string const &EndUseName, std::string const &EndUseSubName)
    3563             :     {
    3564             : 
    3565             :         // SUBROUTINE INFORMATION:
    3566             :         //       AUTHOR         Peter Graham Ellis
    3567             :         //       DATE WRITTEN   February 2006
    3568             :         //       MODIFIED       na
    3569             :         //       RE-ENGINEERED  na
    3570             : 
    3571             :         // PURPOSE OF THIS SUBROUTINE:
    3572             :         // This subroutine manages the list of subcategories for each end-use category.
    3573             : 
    3574             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3575             :         int EndUseSubNum;
    3576             :         int NumSubs;
    3577       39049 :         auto &op(state.dataOutputProcessor);
    3578             : 
    3579       39049 :         bool Found = false;
    3580      204811 :         for (size_t EndUseNum = 1; EndUseNum <= state.dataGlobalConst->iEndUse.size(); ++EndUseNum) {
    3581      204811 :             if (UtilityRoutines::SameString(op->EndUseCategory(EndUseNum).Name, EndUseName)) {
    3582             : 
    3583       44223 :                 for (EndUseSubNum = 1; EndUseSubNum <= op->EndUseCategory(EndUseNum).NumSubcategories; ++EndUseSubNum) {
    3584       38007 :                     if (UtilityRoutines::SameString(op->EndUseCategory(EndUseNum).SubcategoryName(EndUseSubNum), EndUseSubName)) {
    3585             :                         // Subcategory already exists, no further action required
    3586       32833 :                         Found = true;
    3587       32833 :                         break;
    3588             :                     }
    3589             :                 }
    3590             : 
    3591       39049 :                 if (!Found) {
    3592             :                     // Add the subcategory by reallocating the array
    3593        6216 :                     NumSubs = op->EndUseCategory(EndUseNum).NumSubcategories;
    3594        6216 :                     op->EndUseCategory(EndUseNum).SubcategoryName.redimension(NumSubs + 1);
    3595             : 
    3596        6216 :                     op->EndUseCategory(EndUseNum).NumSubcategories = NumSubs + 1;
    3597        6216 :                     op->EndUseCategory(EndUseNum).SubcategoryName(NumSubs + 1) = EndUseSubName;
    3598             : 
    3599        6216 :                     if (op->EndUseCategory(EndUseNum).NumSubcategories > op->MaxNumSubcategories) {
    3600         656 :                         op->MaxNumSubcategories = op->EndUseCategory(EndUseNum).NumSubcategories;
    3601             :                     }
    3602             : 
    3603        6216 :                     Found = true;
    3604             :                 }
    3605       39049 :                 break;
    3606             :             }
    3607             :         }
    3608             : 
    3609       39049 :         if (!Found) {
    3610           0 :             ShowSevereError(state, "Nonexistent end use passed to AddEndUseSubcategory=" + EndUseName);
    3611             :         }
    3612       39049 :     }
    3613        8348 :     void addEndUseSpaceType(EnergyPlusData &state, std::string const &EndUseName, std::string const &EndUseSpaceTypeName)
    3614             :     {
    3615             : 
    3616        8348 :         auto &op(state.dataOutputProcessor);
    3617             : 
    3618        8348 :         bool Found = false;
    3619       33638 :         for (size_t EndUseNum = 1; EndUseNum <= state.dataGlobalConst->iEndUse.size(); ++EndUseNum) {
    3620       33638 :             if (UtilityRoutines::SameString(op->EndUseCategory(EndUseNum).Name, EndUseName)) {
    3621             : 
    3622        8364 :                 for (int endUseSpTypeNum = 1; endUseSpTypeNum <= op->EndUseCategory(EndUseNum).numSpaceTypes; ++endUseSpTypeNum) {
    3623        7083 :                     if (UtilityRoutines::SameString(op->EndUseCategory(EndUseNum).spaceTypeName(endUseSpTypeNum), EndUseSpaceTypeName)) {
    3624             :                         // Space type already exists, no further action required
    3625        7067 :                         Found = true;
    3626        7067 :                         break;
    3627             :                     }
    3628             :                 }
    3629             : 
    3630        8348 :                 if (!Found) {
    3631             :                     // Add the space type by reallocating the array
    3632        1281 :                     int numSpTypes = op->EndUseCategory(EndUseNum).numSpaceTypes;
    3633        1281 :                     op->EndUseCategory(EndUseNum).spaceTypeName.redimension(numSpTypes + 1);
    3634             : 
    3635        1281 :                     op->EndUseCategory(EndUseNum).numSpaceTypes = numSpTypes + 1;
    3636        1281 :                     op->EndUseCategory(EndUseNum).spaceTypeName(numSpTypes + 1) = EndUseSpaceTypeName;
    3637             : 
    3638        1281 :                     if (op->EndUseCategory(EndUseNum).numSpaceTypes > op->maxNumEndUseSpaceTypes) {
    3639           4 :                         op->maxNumEndUseSpaceTypes = op->EndUseCategory(EndUseNum).numSpaceTypes;
    3640             :                     }
    3641             : 
    3642        1281 :                     Found = true;
    3643             :                 }
    3644        8348 :                 break;
    3645             :             }
    3646             :         }
    3647             : 
    3648        8348 :         if (!Found) {
    3649           0 :             ShowSevereError(state, "Nonexistent end use passed to addEndUseSpaceType=" + EndUseName);
    3650             :         }
    3651        8348 :     }
    3652      178102 :     void WriteTimeStampFormatData(
    3653             :         EnergyPlusData &state,
    3654             :         InputOutputFile &outputFile,
    3655             :         ReportingFrequency const reportingInterval, // See Module Parameter Definitions for ReportEach, ReportTimeStep, ReportHourly, etc.
    3656             :         int const reportID,                         // The ID of the time stamp
    3657             :         std::string const &reportIDString,          // The ID of the time stamp
    3658             :         std::string const &DayOfSimChr,             // the number of days simulated so far
    3659             :         bool writeToSQL,
    3660             :         Optional_int_const Month,           // the month of the reporting interval
    3661             :         Optional_int_const DayOfMonth,      // The day of the reporting interval
    3662             :         Optional_int_const Hour,            // The hour of the reporting interval
    3663             :         Optional<Real64 const> EndMinute,   // The last minute in the reporting interval
    3664             :         Optional<Real64 const> StartMinute, // The starting minute of the reporting interval
    3665             :         Optional_int_const DST,             // A flag indicating whether daylight savings time is observed
    3666             :         Optional_string_const DayType       // The day tied for the data (e.g., Monday)
    3667             :     )
    3668             :     {
    3669             : 
    3670             :         // FUNCTION INFORMATION:
    3671             :         //       AUTHOR         Greg Stark
    3672             :         //       DATE WRITTEN   July 2008
    3673             :         //       MODIFIED       na
    3674             :         //       RE-ENGINEERED  na
    3675             : 
    3676             :         // PURPOSE OF THIS FUNCTION:
    3677             :         // This function reports the timestamp data for the output processor
    3678             :         // Much of the code in this function was embedded in earlier versions of EnergyPlus
    3679             :         // and was moved to this location to simplify maintenance and to allow for data output
    3680             :         // to the SQL database
    3681             : 
    3682             :         // METHODOLOGY EMPLOYED:
    3683             :         // na
    3684             : 
    3685             :         // REFERENCES:
    3686             :         // na
    3687             : 
    3688             :         // Using/Aliasing
    3689             :         // Locals
    3690             :         // FUNCTION ARGUMENT DEFINITIONS:
    3691             : 
    3692             :         // FUNCTION PARAMETER DEFINITIONS:
    3693             :         // na
    3694             : 
    3695             :         // INTERFACE BLOCK SPECIFICATIONS:
    3696             :         // na
    3697             : 
    3698             :         // DERIVED TYPE DEFINITIONS:
    3699             :         // na
    3700             : 
    3701             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    3702             : 
    3703      178102 :         assert(reportIDString.length() + DayOfSimChr.length() + (DayType.present() ? DayType().length() : 0u) + 26 <
    3704             :                N_WriteTimeStampFormatData); // Check will fit in stamp size
    3705             : 
    3706      178102 :         if (!outputFile.good()) return;
    3707             : 
    3708      178102 :         switch (reportingInterval) {
    3709      127081 :         case ReportingFrequency::EachCall:
    3710             :         case ReportingFrequency::TimeStep:
    3711      254162 :             print<FormatSyntax::FMT>(outputFile,
    3712             :                                      "{},{},{:2d},{:2d},{:2d},{:2d},{:5.2f},{:5.2f},{}\n",
    3713      254162 :                                      reportIDString.c_str(),
    3714      254162 :                                      DayOfSimChr.c_str(),
    3715             :                                      Month(),
    3716             :                                      DayOfMonth(),
    3717             :                                      DST(),
    3718             :                                      Hour(),
    3719             :                                      StartMinute(),
    3720             :                                      EndMinute(),
    3721      381243 :                                      DayType().c_str());
    3722      127081 :             if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
    3723       85440 :                 state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
    3724             :                                                                                 reportID,
    3725       17088 :                                                                                 state.dataGlobal->DayOfSim,
    3726       17088 :                                                                                 state.dataEnvrn->CurEnvirNum,
    3727       17088 :                                                                                 state.dataGlobal->CalendarYear,
    3728             :                                                                                 Month,
    3729             :                                                                                 DayOfMonth,
    3730             :                                                                                 Hour,
    3731             :                                                                                 EndMinute,
    3732             :                                                                                 StartMinute,
    3733             :                                                                                 DST,
    3734             :                                                                                 DayType,
    3735       17088 :                                                                                 state.dataGlobal->WarmupFlag);
    3736             :             }
    3737      127081 :             break;
    3738       48288 :         case ReportingFrequency::Hourly:
    3739      144864 :             print<FormatSyntax::FMT>(outputFile,
    3740             :                                      "{},{},{:2d},{:2d},{:2d},{:2d},{:5.2f},{:5.2f},{}\n",
    3741       96576 :                                      reportIDString.c_str(),
    3742       96576 :                                      DayOfSimChr.c_str(),
    3743             :                                      Month(),
    3744             :                                      DayOfMonth(),
    3745             :                                      DST(),
    3746             :                                      Hour(),
    3747             :                                      0.0,
    3748             :                                      60.0,
    3749      144864 :                                      DayType().c_str());
    3750       48288 :             if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
    3751       24840 :                 state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
    3752             :                                                                                 reportID,
    3753        4968 :                                                                                 state.dataGlobal->DayOfSim,
    3754        4968 :                                                                                 state.dataEnvrn->CurEnvirNum,
    3755        4968 :                                                                                 state.dataGlobal->CalendarYear,
    3756             :                                                                                 Month,
    3757             :                                                                                 DayOfMonth,
    3758             :                                                                                 Hour,
    3759             :                                                                                 _,
    3760             :                                                                                 _,
    3761             :                                                                                 DST,
    3762             :                                                                                 DayType,
    3763        4968 :                                                                                 state.dataGlobal->WarmupFlag);
    3764             :             }
    3765       48288 :             break;
    3766         142 :         case ReportingFrequency::Daily:
    3767         284 :             print<FormatSyntax::FMT>(outputFile,
    3768             :                                      "{},{},{:2d},{:2d},{:2d},{}\n",
    3769         284 :                                      reportIDString.c_str(),
    3770         284 :                                      DayOfSimChr.c_str(),
    3771             :                                      Month(),
    3772             :                                      DayOfMonth(),
    3773             :                                      DST(),
    3774         426 :                                      DayType().c_str());
    3775         142 :             if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
    3776          85 :                 state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
    3777             :                                                                                 reportID,
    3778          17 :                                                                                 state.dataGlobal->DayOfSim,
    3779          17 :                                                                                 state.dataEnvrn->CurEnvirNum,
    3780          17 :                                                                                 state.dataGlobal->CalendarYear,
    3781             :                                                                                 Month,
    3782             :                                                                                 DayOfMonth,
    3783             :                                                                                 _,
    3784             :                                                                                 _,
    3785             :                                                                                 _,
    3786             :                                                                                 DST,
    3787             :                                                                                 DayType,
    3788          17 :                                                                                 state.dataGlobal->WarmupFlag);
    3789             :             }
    3790         142 :             break;
    3791        1445 :         case ReportingFrequency::Monthly:
    3792        1445 :             print<FormatSyntax::FMT>(outputFile, "{},{},{:2d}\n", reportIDString.c_str(), DayOfSimChr.c_str(), Month());
    3793        1445 :             if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
    3794         460 :                 state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
    3795             :                                                                                 reportID,
    3796         115 :                                                                                 state.dataGlobal->DayOfSim,
    3797         115 :                                                                                 state.dataEnvrn->CurEnvirNum,
    3798         115 :                                                                                 state.dataGlobal->CalendarYear,
    3799             :                                                                                 Month);
    3800             :             }
    3801        1445 :             break;
    3802        1146 :         case ReportingFrequency::Simulation:
    3803        1146 :             print<FormatSyntax::FMT>(outputFile, "{},{}\n", reportIDString.c_str(), DayOfSimChr.c_str());
    3804        1146 :             if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
    3805          32 :                 state.dataSQLiteProcedures->sqlite->createSQLiteTimeIndexRecord(static_cast<int>(reportingInterval),
    3806             :                                                                                 reportID,
    3807           8 :                                                                                 state.dataGlobal->DayOfSim,
    3808           8 :                                                                                 state.dataEnvrn->CurEnvirNum,
    3809           8 :                                                                                 state.dataGlobal->CalendarYear);
    3810             :             }
    3811        1146 :             break;
    3812           0 :         default:
    3813           0 :             if (state.dataSQLiteProcedures->sqlite) {
    3814           0 :                 state.dataSQLiteProcedures->sqlite->sqliteWriteMessage(format<FormatSyntax::FMT>(
    3815           0 :                     "Illegal reportingInterval passed to WriteTimeStampFormatData: {}", static_cast<int>(reportingInterval)));
    3816             :             }
    3817           0 :             break;
    3818             :         }
    3819             :     }
    3820             : 
    3821           0 :     void WriteYearlyTimeStamp(EnergyPlusData &state,
    3822             :                               InputOutputFile &outputFile,
    3823             :                               std::string const &reportIDString, // The ID of the time stamp
    3824             :                               std::string const &yearOfSimChr,   // the year of the simulation
    3825             :                               bool writeToSQL)
    3826             :     {
    3827           0 :         print(outputFile, "{},{}\n", reportIDString, yearOfSimChr);
    3828           0 :         if (writeToSQL && state.dataSQLiteProcedures->sqlite) {
    3829           0 :             state.dataSQLiteProcedures->sqlite->createYearlyTimeIndexRecord(state.dataGlobal->CalendarYear, state.dataEnvrn->CurEnvirNum);
    3830             :         }
    3831           0 :     }
    3832             : 
    3833       58444 :     void WriteReportVariableDictionaryItem(EnergyPlusData &state,
    3834             :                                            ReportingFrequency const reportingInterval, // The reporting interval (e.g., hourly, daily)
    3835             :                                            StoreType const storeType,
    3836             :                                            int const reportID,                       // The reporting ID for the data
    3837             :                                            [[maybe_unused]] int const indexGroupKey, // The reporting group (e.g., Zone, Plant Loop, etc.)
    3838             :                                            std::string const &indexGroup,            // The reporting group (e.g., Zone, Plant Loop, etc.)
    3839             :                                            std::string const &reportIDChr,           // The reporting ID for the data
    3840             :                                            std::string_view const keyedValue,        // The key name for the data
    3841             :                                            std::string_view const variableName,      // The variable's actual name
    3842             :                                            TimeStepType const timeStepType,
    3843             :                                            OutputProcessor::Unit const unitsForVar, // The variables units
    3844             :                                            Optional_string_const customUnitName,
    3845             :                                            std::string_view const ScheduleName)
    3846             :     {
    3847             : 
    3848             :         // SUBROUTINE INFORMATION:
    3849             :         //       AUTHOR         Greg Stark
    3850             :         //       DATE WRITTEN   August 2008
    3851             :         //       MODIFIED       April 2011; Linda Lawrie
    3852             :         //       RE-ENGINEERED  na
    3853             : 
    3854             :         // PURPOSE OF THIS SUBROUTINE:
    3855             :         // This subroutine writes the ESO data dictionary information to the output files
    3856             :         // and the SQL database
    3857             : 
    3858             :         // METHODOLOGY EMPLOYED:
    3859             : 
    3860             :         // REFERENCES:
    3861             :         // na
    3862             : 
    3863             :         // Using/Aliasing
    3864             : 
    3865             :         // Locals
    3866             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    3867             : 
    3868             :         // SUBROUTINE PARAMETER DEFINITIONS:
    3869             :         // na
    3870             : 
    3871             :         // INTERFACE BLOCK SPECIFICATIONS:
    3872             :         // na
    3873             : 
    3874             :         // DERIVED TYPE DEFINITIONS:
    3875             :         // na
    3876             : 
    3877             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3878      116888 :         std::string FreqString;
    3879       58444 :         auto &op(state.dataOutputProcessor);
    3880             : 
    3881       58444 :         FreqString = frequencyNotice(storeType, reportingInterval);
    3882             : 
    3883       58444 :         if (!ScheduleName.empty()) {
    3884        2150 :             FreqString = fmt::format("{},{}", FreqString, ScheduleName);
    3885             :         }
    3886             : 
    3887      116888 :         std::string UnitsString;
    3888       58444 :         if (unitsForVar == OutputProcessor::Unit::customEMS && present(customUnitName)) {
    3889          10 :             UnitsString = customUnitName;
    3890             :         } else {
    3891       58434 :             UnitsString = unitEnumToString(unitsForVar);
    3892             :         }
    3893             : 
    3894       58444 :         const auto write = [&](InputOutputFile &file, const int interval) {
    3895       58444 :             if (file.good()) {
    3896       58444 :                 print(file, "{},{},{},{} [{}]{}\n", reportIDChr, interval, keyedValue, variableName, UnitsString, FreqString);
    3897             :             }
    3898      116888 :         };
    3899       58444 :         switch (reportingInterval) {
    3900       22019 :         case ReportingFrequency::EachCall:
    3901             :         case ReportingFrequency::TimeStep:
    3902       22019 :             write(state.files.eso, 1);
    3903       22019 :             break;
    3904       28427 :         case ReportingFrequency::Hourly:
    3905       28427 :             op->TrackingHourlyVariables = true;
    3906       28427 :             write(state.files.eso, 1);
    3907       28427 :             break;
    3908        4762 :         case ReportingFrequency::Daily:
    3909        4762 :             op->TrackingDailyVariables = true;
    3910        4762 :             write(state.files.eso, 7);
    3911        4762 :             break;
    3912        1599 :         case ReportingFrequency::Monthly:
    3913        1599 :             op->TrackingMonthlyVariables = true;
    3914        1599 :             write(state.files.eso, 9);
    3915        1599 :             break;
    3916         276 :         case ReportingFrequency::Simulation:
    3917         276 :             op->TrackingRunPeriodVariables = true;
    3918         276 :             write(state.files.eso, 11);
    3919         276 :             break;
    3920        1361 :         case ReportingFrequency::Yearly:
    3921        1361 :             op->TrackingYearlyVariables = true;
    3922        1361 :             write(state.files.eso, 11);
    3923        1361 :             break;
    3924           0 :         default:
    3925           0 :             assert(false);
    3926             :         }
    3927             : 
    3928       58444 :         if (state.dataSQLiteProcedures->sqlite) {
    3929       12811 :             state.dataSQLiteProcedures->sqlite->createSQLiteReportDictionaryRecord(reportID,
    3930             :                                                                                    static_cast<int>(storeType),
    3931             :                                                                                    indexGroup,
    3932             :                                                                                    keyedValue,
    3933             :                                                                                    variableName,
    3934             :                                                                                    static_cast<int>(timeStepType),
    3935             :                                                                                    UnitsString,
    3936             :                                                                                    static_cast<int>(reportingInterval),
    3937             :                                                                                    false,
    3938             :                                                                                    ScheduleName);
    3939             :         }
    3940             : 
    3941       58444 :         state.dataResultsFramework->resultsFramework->addReportVariable(keyedValue, variableName, UnitsString, reportingInterval);
    3942             : 
    3943             :         // add to ResultsFramework for output variable list, need to check RVI/MVI later
    3944       58444 :     }
    3945             : 
    3946        7818 :     void WriteMeterDictionaryItem(EnergyPlusData &state,
    3947             :                                   ReportingFrequency const reportingInterval, // The reporting interval (e.g., hourly, daily)
    3948             :                                   StoreType const storeType,
    3949             :                                   int const reportID,                       // The reporting ID in for the variable
    3950             :                                   [[maybe_unused]] int const indexGroupKey, // The reporting group for the variable
    3951             :                                   std::string const &indexGroup,            // The reporting group for the variable
    3952             :                                   std::string const &reportIDChr,           // The reporting ID in for the variable
    3953             :                                   std::string const &meterName,             // The variable's meter name
    3954             :                                   OutputProcessor::Unit const unit,         // The variables units
    3955             :                                   bool const cumulativeMeterFlag,           // A flag indicating cumulative data
    3956             :                                   bool const meterFileOnlyFlag              // A flag indicating whether the data is to be written to standard output
    3957             :     )
    3958             :     {
    3959             : 
    3960             :         // SUBROUTINE INFORMATION:
    3961             :         //       AUTHOR         Greg Stark
    3962             :         //       DATE WRITTEN   August 2008
    3963             :         //       MODIFIED       April 2011; Linda Lawrie
    3964             :         //       RE-ENGINEERED  na
    3965             : 
    3966             :         // PURPOSE OF THIS SUBROUTINE:
    3967             :         // The subroutine writes meter data dictionary information to the output files
    3968             :         // and the SQL database. Much of the code here was embedded in other subroutines
    3969             :         // and was moved here for the purposes of ease of maintenance and to allow easy
    3970             :         // data reporting to the SQL database
    3971             : 
    3972             :         // METHODOLOGY EMPLOYED:
    3973             :         // na
    3974             : 
    3975             :         // REFERENCES:
    3976             :         // na
    3977             : 
    3978             :         // Using/Aliasing
    3979             : 
    3980             :         // Locals
    3981             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    3982             : 
    3983             :         // SUBROUTINE PARAMETER DEFINITIONS:
    3984             :         // na
    3985             : 
    3986             :         // INTERFACE BLOCK SPECIFICATIONS:
    3987             :         // na
    3988             : 
    3989             :         // DERIVED TYPE DEFINITIONS:
    3990             :         // na
    3991             : 
    3992             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3993       15636 :         std::string UnitsString = unitEnumToString(unit);
    3994             : 
    3995       15636 :         std::string const FreqString(frequencyNotice(storeType, reportingInterval));
    3996             : 
    3997        7818 :         const auto print_meter = [&](EnergyPlusData &state, const int frequency) {
    3998        9868 :             const auto out = [&](InputOutputFile &of) {
    3999        9868 :                 if (of.good()) {
    4000       17686 :                     if (cumulativeMeterFlag) {
    4001             :                         static constexpr std::string_view fmt{"{},{},Cumulative {} [{}]{}\n"};
    4002       17686 :                         const auto lenString = index(FreqString, '[');
    4003       43184 :                         print(of, fmt, reportIDChr, 1, meterName, UnitsString, FreqString.substr(0, lenString));
    4004             :                     } else {
    4005             :                         static constexpr std::string_view fmt{"{},{},{} [{}]{}\n"};
    4006       19724 :                         print(of, fmt, reportIDChr, frequency, meterName, UnitsString, FreqString);
    4007             :                     }
    4008             :                 }
    4009       48958 :             };
    4010             : 
    4011        7818 :             out(state.files.mtr);
    4012        7818 :             if (!meterFileOnlyFlag) {
    4013        2050 :                 out(state.files.eso);
    4014             :             }
    4015       15636 :         };
    4016             : 
    4017        7818 :         switch (reportingInterval) {
    4018         749 :         case ReportingFrequency::EachCall:
    4019             :         case ReportingFrequency::TimeStep:
    4020             :         case ReportingFrequency::Hourly: // -1, 0, 1
    4021         749 :             print_meter(state, 1);
    4022         749 :             break;
    4023          71 :         case ReportingFrequency::Daily: //  2
    4024          71 :             print_meter(state, 7);
    4025          71 :             break;
    4026        4090 :         case ReportingFrequency::Monthly: //  3
    4027        4090 :             print_meter(state, 9);
    4028        4090 :             break;
    4029        2908 :         case ReportingFrequency::Yearly:     //  5
    4030             :         case ReportingFrequency::Simulation: //  4
    4031        2908 :             print_meter(state, 11);
    4032        2908 :             break;
    4033           0 :         default:
    4034           0 :             assert(false);
    4035             :         }
    4036             : 
    4037             :         static constexpr std::string_view keyedValueStringCum("Cumulative ");
    4038             :         static constexpr std::string_view keyedValueStringNon;
    4039        7818 :         std::string_view const keyedValueString(cumulativeMeterFlag ? keyedValueStringCum : keyedValueStringNon);
    4040             : 
    4041        7818 :         if (state.dataSQLiteProcedures->sqlite) {
    4042        3244 :             state.dataSQLiteProcedures->sqlite->createSQLiteReportDictionaryRecord(reportID,
    4043             :                                                                                    static_cast<int>(storeType),
    4044             :                                                                                    indexGroup,
    4045             :                                                                                    keyedValueString,
    4046             :                                                                                    meterName,
    4047             :                                                                                    1,
    4048             :                                                                                    UnitsString,
    4049             :                                                                                    static_cast<int>(reportingInterval),
    4050        1622 :                                                                                    true);
    4051             :         }
    4052             : 
    4053        7818 :         state.dataResultsFramework->resultsFramework->addReportMeter(meterName, UnitsString, reportingInterval);
    4054             :         // add to ResultsFramework for output variable list, need to check RVI/MVI later
    4055        7818 :     }
    4056             : 
    4057     1303999 :     void WriteRealVariableOutput(EnergyPlusData &state,
    4058             :                                  RealVariables &realVar,             // Real variable to write out
    4059             :                                  ReportingFrequency const reportType // The report type or interval (e.g., hourly)
    4060             :     )
    4061             :     {
    4062             : 
    4063             :         // SUBROUTINE INFORMATION:
    4064             :         //       AUTHOR         Greg Stark
    4065             :         //       DATE WRITTEN   August 2008
    4066             :         //       MODIFIED       April 2011; Linda Lawrie, December 2017; Jason DeGraw
    4067             :         //       RE-ENGINEERED  na
    4068             : 
    4069             :         // PURPOSE OF THIS SUBROUTINE:
    4070             :         // This subroutine writes real report variable data to the output file and
    4071             :         // SQL database. Much of the code here was an included in earlier versions
    4072             :         // of the UpdateDataandReport subroutine. The code was moved to facilitate
    4073             :         // easier maintenance and writing of data to the SQL database.
    4074             : 
    4075             :         // METHODOLOGY EMPLOYED:
    4076             :         // na
    4077             : 
    4078             :         // REFERENCES:
    4079             :         // na
    4080             : 
    4081             :         // USE STATEMENTS:
    4082             : 
    4083             :         // Locals
    4084             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    4085             : 
    4086             :         // SUBROUTINE PARAMETER DEFINITIONS:
    4087             :         // na
    4088             : 
    4089             :         // INTERFACE BLOCK SPECIFICATIONS:
    4090             :         // na
    4091             : 
    4092             :         // DERIVED TYPE DEFINITIONS:
    4093             :         // na
    4094             : 
    4095             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4096             :         // na
    4097             : 
    4098     1303999 :         if (realVar.Report && realVar.frequency == reportType && realVar.Stored) {
    4099       34277 :             if (realVar.NumStored > 0.0) {
    4100       34271 :                 WriteReportRealData(state,
    4101             :                                     realVar.ReportID,
    4102             :                                     realVar.ReportIDChr,
    4103             :                                     realVar.StoreValue,
    4104             :                                     realVar.storeType,
    4105             :                                     realVar.NumStored,
    4106             :                                     realVar.frequency,
    4107             :                                     realVar.MinValue,
    4108             :                                     realVar.minValueDate,
    4109             :                                     realVar.MaxValue,
    4110             :                                     realVar.maxValueDate);
    4111       34271 :                 ++state.dataGlobal->StdOutputRecordCount;
    4112             :             }
    4113             : 
    4114       34277 :             realVar.StoreValue = 0.0;
    4115       34277 :             realVar.NumStored = 0.0;
    4116       34277 :             realVar.MinValue = MinSetValue;
    4117       34277 :             realVar.MaxValue = MaxSetValue;
    4118       34277 :             realVar.Stored = false;
    4119             :         }
    4120     1303999 :     }
    4121             : 
    4122       34271 :     void WriteReportRealData(EnergyPlusData &state,
    4123             :                              int const reportID,
    4124             :                              std::string const &creportID,
    4125             :                              Real64 const repValue,
    4126             :                              StoreType const storeType,
    4127             :                              Real64 const numOfItemsStored,
    4128             :                              ReportingFrequency const reportingInterval,
    4129             :                              Real64 const minValue,
    4130             :                              int const minValueDate,
    4131             :                              Real64 const MaxValue,
    4132             :                              int const maxValueDate)
    4133             :     {
    4134             : 
    4135             :         // SUBROUTINE INFORMATION:
    4136             :         //       AUTHOR         Greg Stark
    4137             :         //       DATE WRITTEN   July 2008
    4138             :         //       MODIFIED       April 2011; Linda Lawrie
    4139             :         //       RE-ENGINEERED  na
    4140             : 
    4141             :         // PURPOSE OF THIS SUBROUTINE:
    4142             :         // This subroutine writes the average real data to the output files and
    4143             :         // SQL database. It supports the WriteRealVariableOutput subroutine.
    4144             :         // Much of the code here was an included in earlier versions
    4145             :         // of the UpdateDataandReport subroutine. The code was moved to facilitate
    4146             :         // easier maintenance and writing of data to the SQL database.
    4147             : 
    4148       68542 :         std::string NumberOut;   // Character for producing "number out"
    4149       34271 :         Real64 repVal(repValue); // The variable's value
    4150             : 
    4151       34271 :         if (storeType == StoreType::Averaged) {
    4152       29353 :             repVal /= numOfItemsStored;
    4153             :         }
    4154       34271 :         if (repVal == 0.0) {
    4155        6088 :             NumberOut = "0.0";
    4156             :         } else {
    4157       28183 :             dtoa(repVal, state.dataOutputProcessor->s_WriteReportRealData);
    4158       28183 :             NumberOut = std::string(state.dataOutputProcessor->s_WriteReportRealData);
    4159             :         }
    4160             : 
    4161       34271 :         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    4162             :             //// The others (<= hourly) are handled inline with the code
    4163             :             // add to daily TS data store
    4164           0 :             if (reportingInterval == ReportingFrequency::Daily) {
    4165           0 :                 state.dataResultsFramework->resultsFramework->RIDailyTSData.pushVariableValue(reportID, repVal);
    4166             :             }
    4167             :             // add to monthly TS data store
    4168           0 :             if (reportingInterval == ReportingFrequency::Monthly) {
    4169           0 :                 state.dataResultsFramework->resultsFramework->RIMonthlyTSData.pushVariableValue(reportID, repVal);
    4170             :             }
    4171             :             // add to run period TS data store
    4172           0 :             if (reportingInterval == ReportingFrequency::Simulation) {
    4173           0 :                 state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.pushVariableValue(reportID, repVal);
    4174             :             }
    4175             :             // add to annual TS data store
    4176           0 :             if (reportingInterval == ReportingFrequency::Yearly) {
    4177           0 :                 state.dataResultsFramework->resultsFramework->RIYearlyTSData.pushVariableValue(reportID, repVal);
    4178             :             }
    4179             :         }
    4180             : 
    4181       34271 :         if (state.dataSQLiteProcedures->sqlite) {
    4182        5100 :             state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(
    4183        3400 :                 reportID, repVal, static_cast<int>(reportingInterval), minValue, minValueDate, MaxValue, maxValueDate);
    4184             :         }
    4185             : 
    4186       34271 :         if ((reportingInterval == ReportingFrequency::EachCall) || (reportingInterval == ReportingFrequency::TimeStep) ||
    4187             :             (reportingInterval == ReportingFrequency::Hourly)) { // -1, 0, 1
    4188           0 :             if (state.files.eso.good()) {
    4189           0 :                 print(state.files.eso, "{},{}\n", creportID, NumberOut);
    4190             :             }
    4191             : 
    4192             :         } else { // if ( ( reportingInterval == ReportingFrequency::Daily ) || ( reportingInterval == ReportingFrequency::Monthly ) || (
    4193             :                  // reportingInterval == ReportingFrequency::Simulation ) ) { //  2, 3, 4, 5
    4194       68542 :             std::string MaxOut; // Character for Max out string
    4195       68542 :             std::string MinOut; // Character for Min out string
    4196             : 
    4197       34271 :             if (MaxValue == 0.0) {
    4198        6132 :                 MaxOut = "0.0";
    4199             :             } else {
    4200       28139 :                 dtoa(MaxValue, state.dataOutputProcessor->s_WriteReportRealData);
    4201       28139 :                 MaxOut = std::string(state.dataOutputProcessor->s_WriteReportRealData);
    4202             :             }
    4203             : 
    4204       34271 :             if (minValue == 0.0) {
    4205       15867 :                 MinOut = "0.0";
    4206             :             } else {
    4207       18404 :                 dtoa(minValue, state.dataOutputProcessor->s_WriteReportRealData);
    4208       18404 :                 MinOut = std::string(state.dataOutputProcessor->s_WriteReportRealData);
    4209             :             }
    4210             : 
    4211             :             // Append the min and max strings with date information
    4212       34271 :             ProduceMinMaxString(MinOut, minValueDate, reportingInterval);
    4213       34271 :             ProduceMinMaxString(MaxOut, maxValueDate, reportingInterval);
    4214             : 
    4215       34271 :             if (state.files.eso.good()) {
    4216       34271 :                 print(state.files.eso, "{},{},{},{}\n", creportID, NumberOut, MinOut, MaxOut);
    4217             :             }
    4218             :         }
    4219       34271 :     }
    4220             : 
    4221          10 :     void WriteCumulativeReportMeterData(EnergyPlusData &state,
    4222             :                                         int const reportID,           // The variable's report ID
    4223             :                                         std::string const &creportID, // variable ID in characters
    4224             :                                         Real64 const repValue,        // The variable's value
    4225             :                                         bool const meterOnlyFlag      // A flag that indicates if the data should be written to standard output
    4226             :     )
    4227             :     {
    4228             : 
    4229             :         // SUBROUTINE INFORMATION:
    4230             :         //       AUTHOR         Greg Stark
    4231             :         //       DATE WRITTEN   July 2008
    4232             :         //       MODIFIED       na
    4233             :         //       RE-ENGINEERED  na
    4234             : 
    4235             :         // PURPOSE OF THIS SUBROUTINE:
    4236             :         // This subroutine writes the cumulative meter data to the output files and
    4237             :         // SQL database.
    4238             : 
    4239          20 :         std::string NumberOut; // Character for producing "number out"
    4240             : 
    4241          10 :         if (repValue == 0.0) {
    4242           0 :             NumberOut = "0.0";
    4243             :         } else {
    4244          10 :             dtoa(repValue, state.dataOutputProcessor->s_WriteCumulativeReportMeterData);
    4245          10 :             NumberOut = std::string(state.dataOutputProcessor->s_WriteCumulativeReportMeterData);
    4246             :         }
    4247             : 
    4248          10 :         if (state.dataSQLiteProcedures->sqlite) {
    4249           4 :             state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(reportID, repValue);
    4250             :         }
    4251             : 
    4252          10 :         if (state.files.mtr.good()) print(state.files.mtr, "{},{}\n", creportID, NumberOut);
    4253          10 :         ++state.dataGlobal->StdMeterRecordCount;
    4254             : 
    4255          10 :         if (!meterOnlyFlag) {
    4256           2 :             if (state.files.eso.good()) print(state.files.eso, "{},{}\n", creportID, NumberOut);
    4257           2 :             ++state.dataGlobal->StdOutputRecordCount;
    4258             :         }
    4259          10 :     }
    4260             : 
    4261       81710 :     void WriteReportMeterData(EnergyPlusData &state,
    4262             :                               int const reportID,                         // The variable's report ID
    4263             :                               std::string const &creportID,               // variable ID in characters
    4264             :                               Real64 const repValue,                      // The variable's value
    4265             :                               ReportingFrequency const reportingInterval, // The variable's reporting interval (e.g., hourly)
    4266             :                               Real64 const minValue,                      // The variable's minimum value during the reporting interval
    4267             :                               int const minValueDate,                     // The date the minimum value occurred
    4268             :                               Real64 const MaxValue,                      // The variable's maximum value during the reporting interval
    4269             :                               int const maxValueDate,                     // The date of the maximum value
    4270             :                               bool const meterOnlyFlag                    // Indicates whether the data is for the meter file only
    4271             :     )
    4272             :     {
    4273             : 
    4274             :         // SUBROUTINE INFORMATION:
    4275             :         //       AUTHOR         Greg Stark
    4276             :         //       DATE WRITTEN   July 2008
    4277             :         //       MODIFIED       na
    4278             :         //       RE-ENGINEERED  na
    4279             : 
    4280             :         // PURPOSE OF THIS SUBROUTINE:
    4281             :         // This subroutine writes for the non-cumulative meter data to the output files and
    4282             :         // SQL database.
    4283             : 
    4284      163420 :         std::string NumberOut; // Character for producing "number out"
    4285             : 
    4286       81710 :         if (repValue == 0.0) {
    4287       28018 :             NumberOut = "0.0";
    4288             :         } else {
    4289       53692 :             dtoa(repValue, state.dataOutputProcessor->s_WriteReportMeterData);
    4290       53692 :             NumberOut = std::string(state.dataOutputProcessor->s_WriteReportMeterData);
    4291             :         }
    4292             : 
    4293       81710 :         if (state.dataSQLiteProcedures->sqlite) {
    4294      167568 :             state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(reportID,
    4295             :                                                                              repValue,
    4296       83784 :                                                                              static_cast<int>(reportingInterval),
    4297             :                                                                              minValue,
    4298             :                                                                              minValueDate,
    4299             :                                                                              MaxValue,
    4300             :                                                                              maxValueDate,
    4301       41892 :                                                                              state.dataGlobal->MinutesPerTimeStep);
    4302             :         }
    4303             : 
    4304       81710 :         if ((reportingInterval == ReportingFrequency::EachCall) || (reportingInterval == ReportingFrequency::TimeStep) ||
    4305             :             (reportingInterval == ReportingFrequency::Hourly)) { // -1, 0, 1
    4306       65328 :             if (state.files.mtr.good()) {
    4307       65328 :                 print(state.files.mtr, "{},{}\n", creportID, NumberOut);
    4308             :             }
    4309       65328 :             ++state.dataGlobal->StdMeterRecordCount;
    4310      130656 :             if (state.files.eso.good() && !meterOnlyFlag) {
    4311       55200 :                 print(state.files.eso, "{},{}\n", creportID, NumberOut);
    4312       55200 :                 ++state.dataGlobal->StdOutputRecordCount;
    4313             :             }
    4314             :         } else { // if ( ( reportingInterval == ReportDaily ) || ( reportingInterval == ReportMonthly ) || ( reportingInterval == ReportSim ) ) {
    4315             :                  // // 2, 3, 4
    4316       32764 :             std::string MaxOut; // Character for Max out string
    4317       32764 :             std::string MinOut; // Character for Min out string
    4318             : 
    4319       16382 :             if (MaxValue == 0.0) {
    4320        1900 :                 MaxOut = "0.0";
    4321             :             } else {
    4322       14482 :                 dtoa(MaxValue, state.dataOutputProcessor->s_WriteReportMeterData);
    4323       14482 :                 MaxOut = std::string(state.dataOutputProcessor->s_WriteReportMeterData);
    4324             :             }
    4325             : 
    4326       16382 :             if (minValue == 0.0) {
    4327        3813 :                 MinOut = "0.0";
    4328             :             } else {
    4329       12569 :                 dtoa(minValue, state.dataOutputProcessor->s_WriteReportMeterData);
    4330       12569 :                 MinOut = std::string(state.dataOutputProcessor->s_WriteReportMeterData);
    4331             :             }
    4332             : 
    4333             :             // Append the min and max strings with date information
    4334       16382 :             ProduceMinMaxString(MinOut, minValueDate, reportingInterval);
    4335       16382 :             ProduceMinMaxString(MaxOut, maxValueDate, reportingInterval);
    4336             : 
    4337       16382 :             if (state.files.mtr.good()) {
    4338       16382 :                 print(state.files.mtr, "{},{},{},{}\n", creportID, NumberOut, MinOut, MaxOut);
    4339             :             }
    4340             : 
    4341       16382 :             ++state.dataGlobal->StdMeterRecordCount;
    4342       16382 :             if (state.files.eso.good() && !meterOnlyFlag) {
    4343        3382 :                 print(state.files.eso, "{},{},{},{}\n", creportID, NumberOut, MinOut, MaxOut);
    4344        3382 :                 ++state.dataGlobal->StdOutputRecordCount;
    4345             :             }
    4346             :         }
    4347       81710 :     }
    4348             : 
    4349     9860796 :     void WriteNumericData(EnergyPlusData &state,
    4350             :                           int const reportID,           // The variable's reporting ID
    4351             :                           std::string const &creportID, // variable ID in characters
    4352             :                           Real64 const repValue         // The variable's value
    4353             :     )
    4354             :     {
    4355             :         // SUBROUTINE INFORMATION:
    4356             :         //       AUTHOR         Mark Adams
    4357             :         //       DATE WRITTEN   May 2016
    4358             :         //       MODIFIED       na
    4359             :         //       RE-ENGINEERED  na
    4360             : 
    4361             :         // PURPOSE:
    4362             :         // This subroutine writes real data to the output files and
    4363             :         // SQL database.
    4364             :         // This is a refactor of WriteRealData.
    4365             :         //
    4366             :         // Much of the code here was an included in earlier versions
    4367             :         // of the UpdateDataandReport subroutine. The code was moved to facilitate
    4368             :         // easier maintenance and writing of data to the SQL database.
    4369             : 
    4370     9860796 :         if (state.dataSysVars->UpdateDataDuringWarmupExternalInterface && !state.dataSysVars->ReportDuringWarmup) return;
    4371             : 
    4372     9860796 :         dtoa(repValue, state.dataOutputProcessor->s_WriteNumericData);
    4373             : 
    4374     9860796 :         if (state.dataSQLiteProcedures->sqlite) {
    4375     1935519 :             state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(reportID, repValue);
    4376             :         }
    4377             : 
    4378     9860796 :         if (state.files.eso.good()) {
    4379     9860796 :             print<FormatSyntax::FMT>(state.files.eso, "{},{}\n", creportID, state.dataOutputProcessor->s_WriteNumericData);
    4380             :         }
    4381             :     }
    4382             : 
    4383        7320 :     void WriteNumericData(EnergyPlusData &state,
    4384             :                           int const reportID,           // The variable's reporting ID
    4385             :                           std::string const &creportID, // variable ID in characters
    4386             :                           int32_t const repValue        // The variable's value
    4387             :     )
    4388             :     {
    4389             :         // SUBROUTINE INFORMATION:
    4390             :         //       AUTHOR         Mark Adams
    4391             :         //       DATE WRITTEN   May 2016
    4392             :         //       MODIFIED       na
    4393             :         //       RE-ENGINEERED  na
    4394             : 
    4395             :         // PURPOSE:
    4396             :         // This subroutine writes real data to the output files and
    4397             :         // SQL database.
    4398             :         // This is a refactor of WriteIntegerData.
    4399             :         //
    4400             :         // Much of the code here was an included in earlier versions
    4401             :         // of the UpdateDataandReport subroutine. The code was moved to facilitate
    4402             :         // easier maintenance and writing of data to the SQL database.
    4403             : 
    4404             :         //        i32toa(repValue, state.dataOutputProcessor->s_WriteNumericData);
    4405             : 
    4406        7320 :         if (state.dataSQLiteProcedures->sqlite) {
    4407         259 :             state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(reportID, repValue);
    4408             :         }
    4409             : 
    4410        7320 :         if (state.files.eso.good()) {
    4411        7320 :             print<FormatSyntax::FMT>(state.files.eso, "{},{}\n", creportID, fmt::format_int(repValue).c_str());
    4412             :         }
    4413        7320 :     }
    4414             : 
    4415       26479 :     void WriteIntegerVariableOutput(EnergyPlusData &state,
    4416             :                                     IntegerVariables &intVar,           // Integer variable to write out
    4417             :                                     ReportingFrequency const reportType // The report type (i.e., the reporting interval)
    4418             :     )
    4419             :     {
    4420             : 
    4421             :         // SUBROUTINE INFORMATION:
    4422             :         //       AUTHOR         Greg Stark
    4423             :         //       DATE WRITTEN   August 2008
    4424             :         //       MODIFIED       April 2011; Linda Lawrie, December 2017; Jason DeGraw
    4425             :         //       RE-ENGINEERED  na
    4426             : 
    4427             :         // PURPOSE OF THIS SUBROUTINE:
    4428             :         // This subroutine writes integer report variable data to the output file and
    4429             :         // SQL database. Much of the code here was an included in earlier versions
    4430             :         // of the UpdateDataandReport subroutine. The code was moved to facilitate
    4431             :         // easier maintenance and writing of data to the SQL database.
    4432             : 
    4433             :         // METHODOLOGY EMPLOYED:
    4434             :         // na
    4435             : 
    4436             :         // REFERENCES:
    4437             :         // na
    4438             : 
    4439             :         // Using/Aliasing
    4440             : 
    4441             :         // Locals
    4442             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    4443             : 
    4444             :         // SUBROUTINE PARAMETER DEFINITIONS:
    4445             :         // na
    4446             : 
    4447             :         // INTERFACE BLOCK SPECIFICATIONS:
    4448             :         // na
    4449             : 
    4450             :         // DERIVED TYPE DEFINITIONS:
    4451             :         // na
    4452             : 
    4453             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4454             :         // na
    4455             : 
    4456       26479 :         if (state.dataSysVars->UpdateDataDuringWarmupExternalInterface && !state.dataSysVars->ReportDuringWarmup) return;
    4457             : 
    4458       26479 :         if (intVar.Report && intVar.frequency == reportType && intVar.Stored) {
    4459         404 :             if (intVar.NumStored > 0.0) {
    4460         404 :                 WriteReportIntegerData(state,
    4461             :                                        intVar.ReportID,
    4462             :                                        intVar.ReportIDChr,
    4463             :                                        intVar.StoreValue,
    4464             :                                        intVar.storeType,
    4465             :                                        intVar.NumStored,
    4466             :                                        intVar.frequency,
    4467             :                                        intVar.MinValue,
    4468             :                                        intVar.minValueDate,
    4469             :                                        intVar.MaxValue,
    4470             :                                        intVar.maxValueDate);
    4471         404 :                 ++state.dataGlobal->StdOutputRecordCount;
    4472             :             }
    4473             : 
    4474         404 :             intVar.StoreValue = 0.0;
    4475         404 :             intVar.NumStored = 0.0;
    4476         404 :             intVar.MinValue = IMinSetValue;
    4477         404 :             intVar.MaxValue = IMaxSetValue;
    4478         404 :             intVar.Stored = false;
    4479             :         }
    4480             :     }
    4481             : 
    4482         404 :     void WriteReportIntegerData(EnergyPlusData &state,
    4483             :                                 int const reportID,                         // The variable's reporting ID
    4484             :                                 std::string const &reportIDString,          // The variable's reporting ID (character)
    4485             :                                 Real64 const repValue,                      // The variable's value
    4486             :                                 StoreType const storeType,                  // Type of item (averaged or summed)
    4487             :                                 Real64 const numOfItemsStored,              // The number of items (hours or timesteps) of data stored
    4488             :                                 ReportingFrequency const reportingInterval, // The reporting interval (e.g., monthly)
    4489             :                                 int const minValue,                         // The variable's minimum value during the reporting interval
    4490             :                                 int const minValueDate,                     // The date the minimum value occurred
    4491             :                                 int const MaxValue,                         // The variable's maximum value during the reporting interval
    4492             :                                 int const maxValueDate                      // The date the maximum value occurred
    4493             :     )
    4494             :     {
    4495             : 
    4496             :         // SUBROUTINE INFORMATION:
    4497             :         //       AUTHOR         Greg Stark
    4498             :         //       DATE WRITTEN   July 2008
    4499             :         //       MODIFIED       April 2011; Linda Lawrie
    4500             :         //       RE-ENGINEERED  na
    4501             : 
    4502             :         // PURPOSE OF THIS SUBROUTINE:
    4503             :         // This subroutine writes averaged integer data to the output files and
    4504             :         // SQL database. It supports the WriteIntegerVariableOutput subroutine.
    4505             :         // Much of the code here was an included in earlier versions
    4506             :         // of the UpdateDataandReport subroutine. The code was moved to facilitate
    4507             :         // easier maintenance and writing of data to the SQL database.
    4508             : 
    4509             :         // METHODOLOGY EMPLOYED:
    4510             :         // na
    4511             : 
    4512             :         // REFERENCES:
    4513             :         // na
    4514             : 
    4515             :         // Using/Aliasing
    4516             :         using General::strip_trailing_zeros;
    4517             : 
    4518             :         // Locals
    4519             : 
    4520             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    4521             : 
    4522             :         // SUBROUTINE PARAMETER DEFINITIONS:
    4523             : 
    4524             :         // INTERFACE BLOCK SPECIFICATIONS:
    4525             :         // na
    4526             : 
    4527             :         // DERIVED TYPE DEFINITIONS:
    4528             :         // na
    4529             : 
    4530             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4531         808 :         std::string NumberOut; // Character for producing "number out"
    4532         808 :         std::string MaxOut;    // Character for Max out string
    4533         808 :         std::string MinOut;    // Character for Min out string
    4534             :         Real64 rmaxValue;
    4535             :         Real64 rminValue;
    4536             :         Real64 repVal; // The variable's value
    4537             : 
    4538         404 :         repVal = repValue;
    4539         404 :         if (storeType == StoreType::Averaged) {
    4540         364 :             repVal /= numOfItemsStored;
    4541             :         }
    4542         404 :         if (repValue == 0.0) {
    4543          74 :             NumberOut = "0.0";
    4544             :         } else {
    4545         330 :             NumberOut = format("{:N}", repVal);
    4546         330 :             strip_trailing_zeros(strip(NumberOut));
    4547             :         }
    4548             : 
    4549             :         // Append the min and max strings with date information
    4550         404 :         MinOut = fmt::to_string(minValue);
    4551         404 :         MaxOut = fmt::to_string(MaxValue);
    4552         404 :         ProduceMinMaxString(MinOut, minValueDate, reportingInterval);
    4553         404 :         ProduceMinMaxString(MaxOut, maxValueDate, reportingInterval);
    4554             : 
    4555         404 :         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    4556             :             // add to daily TS data store
    4557           0 :             if (reportingInterval == ReportingFrequency::Daily) {
    4558           0 :                 state.dataResultsFramework->resultsFramework->RIDailyTSData.pushVariableValue(reportID, repVal);
    4559             :             }
    4560             :             // add to monthly TS data store
    4561           0 :             if (reportingInterval == ReportingFrequency::Monthly) {
    4562           0 :                 state.dataResultsFramework->resultsFramework->RIMonthlyTSData.pushVariableValue(reportID, repVal);
    4563             :             }
    4564             :             // add to run period TS data store
    4565           0 :             if (reportingInterval == ReportingFrequency::Simulation) {
    4566           0 :                 state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.pushVariableValue(reportID, repVal);
    4567             :             }
    4568             :             // add to annual TS data store
    4569           0 :             if (reportingInterval == ReportingFrequency::Yearly) {
    4570           0 :                 state.dataResultsFramework->resultsFramework->RIYearlyTSData.pushVariableValue(reportID, repVal);
    4571             :             }
    4572             :         }
    4573             : 
    4574         404 :         rminValue = minValue;
    4575         404 :         rmaxValue = MaxValue;
    4576         404 :         if (state.dataSQLiteProcedures->sqlite) {
    4577          12 :             state.dataSQLiteProcedures->sqlite->createSQLiteReportDataRecord(
    4578           8 :                 reportID, repVal, static_cast<int>(reportingInterval), rminValue, minValueDate, rmaxValue, maxValueDate);
    4579             :         }
    4580             : 
    4581         404 :         if ((reportingInterval == ReportingFrequency::EachCall) || (reportingInterval == ReportingFrequency::TimeStep) ||
    4582             :             (reportingInterval == ReportingFrequency::Hourly)) { // -1, 0, 1
    4583           0 :             if (state.files.eso.good()) {
    4584           0 :                 print(state.files.eso, "{},{}\n", reportIDString, NumberOut);
    4585             :             }
    4586             :         } else { // if ( ( reportingInterval == ReportDaily ) || ( reportingInterval == ReportMonthly ) || ( reportingInterval == ReportSim ) ) {
    4587             :                  // // 2, 3, 4
    4588         404 :             if (state.files.eso.good()) {
    4589         404 :                 print(state.files.eso, "{},{},{},{}\n", reportIDString, NumberOut, MinOut, MaxOut);
    4590             :             }
    4591             :         }
    4592         404 :     }
    4593             : 
    4594        7880 :     int DetermineIndexGroupKeyFromMeterName(EnergyPlusData &state, std::string const &meterName) // the meter name
    4595             :     {
    4596             : 
    4597             :         // FUNCTION INFORMATION:
    4598             :         //       AUTHOR         Greg Stark
    4599             :         //       DATE WRITTEN   May 2009
    4600             :         //       MODIFIED       na
    4601             :         //       RE-ENGINEERED  na
    4602             : 
    4603             :         // PURPOSE OF THIS FUNCTION:
    4604             :         // This function attemps to guess determine how a meter variable should be
    4605             :         // grouped.  It does this by parsing the meter name and then assigns a
    4606             :         // indexGroupKey based on the name
    4607             : 
    4608             :         // METHODOLOGY EMPLOYED:
    4609             :         // na
    4610             : 
    4611             :         // REFERENCES:
    4612             :         // na
    4613             : 
    4614             :         // USE STATEMENTS:
    4615             :         // na
    4616             : 
    4617             :         // Return value
    4618             :         int DetermineIndexGroupKeyFromMeterName;
    4619             : 
    4620             :         // Locals
    4621             :         // FUNCTION ARGUMENT DEFINITIONS:
    4622             : 
    4623             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    4624             : 
    4625             :         // Facility indices are in the 100s
    4626        7880 :         if (has(meterName, "Electricity:Facility")) {
    4627        1140 :             state.dataOutputProcessor->indexGroupKey = 100;
    4628        6740 :         } else if (has(meterName, "NaturalGas:Facility")) {
    4629         686 :             state.dataOutputProcessor->indexGroupKey = 101;
    4630        6054 :         } else if (has(meterName, "DistricHeating:Facility")) {
    4631           0 :             state.dataOutputProcessor->indexGroupKey = 102;
    4632        6054 :         } else if (has(meterName, "DistricCooling:Facility")) {
    4633           0 :             state.dataOutputProcessor->indexGroupKey = 103;
    4634        6054 :         } else if (has(meterName, "ElectricityNet:Facility")) {
    4635          18 :             state.dataOutputProcessor->indexGroupKey = 104;
    4636             : 
    4637             :             // Building indices are in the 200s
    4638        6036 :         } else if (has(meterName, "Electricity:Building")) {
    4639         943 :             state.dataOutputProcessor->indexGroupKey = 201;
    4640        5093 :         } else if (has(meterName, "NaturalGas:Building")) {
    4641           8 :             state.dataOutputProcessor->indexGroupKey = 202;
    4642             : 
    4643             :             // HVAC indices are in the 300s
    4644        5085 :         } else if (has(meterName, "Electricity:HVAC")) {
    4645         836 :             state.dataOutputProcessor->indexGroupKey = 301;
    4646             : 
    4647             :             // InteriorLights:Electricity:Zone indices are in the 500s
    4648        4249 :         } else if (has(meterName, "InteriorLights:Electricity:Zone")) {
    4649          14 :             state.dataOutputProcessor->indexGroupKey = 501;
    4650             : 
    4651             :             // InteriorLights:Electricity indices are in the 400s
    4652        4235 :         } else if (has(meterName, "InteriorLights:Electricity")) {
    4653         958 :             state.dataOutputProcessor->indexGroupKey = 401;
    4654             : 
    4655             :             // Unknown items have negative indices
    4656             :         } else {
    4657        3277 :             state.dataOutputProcessor->indexGroupKey = -11;
    4658             :         }
    4659             : 
    4660        7880 :         DetermineIndexGroupKeyFromMeterName = state.dataOutputProcessor->indexGroupKey;
    4661             : 
    4662        7880 :         return DetermineIndexGroupKeyFromMeterName;
    4663             :     }
    4664             : 
    4665        7880 :     std::string DetermineIndexGroupFromMeterGroup(MeterType const &meter) // the meter
    4666             :     {
    4667             : 
    4668             :         // FUNCTION INFORMATION:
    4669             :         //       AUTHOR         Greg Stark
    4670             :         //       DATE WRITTEN   May 2009
    4671             :         //       MODIFIED       na
    4672             :         //       RE-ENGINEERED  na
    4673             : 
    4674             :         // PURPOSE OF THIS FUNCTION:
    4675             :         // This function attemps to determine how a meter variable should be
    4676             :         // grouped.  It does this by parsing the meter group
    4677             : 
    4678             :         // METHODOLOGY EMPLOYED:
    4679             :         // na
    4680             : 
    4681             :         // REFERENCES:
    4682             :         // na
    4683             : 
    4684             :         // USE STATEMENTS:
    4685             :         // na
    4686             : 
    4687             :         // Return value
    4688        7880 :         std::string indexGroup;
    4689             : 
    4690             :         // Locals
    4691             :         // FUNCTION ARGUMENT DEFINITIONS:
    4692             : 
    4693             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    4694             : 
    4695        7880 :         if (len(meter.Group) > 0) {
    4696        3077 :             indexGroup = meter.Group;
    4697             :         } else {
    4698        4803 :             indexGroup = "Facility";
    4699             :         }
    4700             : 
    4701        7880 :         if (len(meter.ResourceType) > 0) {
    4702        7880 :             indexGroup += ":" + meter.ResourceType;
    4703             :         }
    4704             : 
    4705        7880 :         if (len(meter.EndUse) > 0) {
    4706        1615 :             indexGroup += ":" + meter.EndUse;
    4707             :         }
    4708             : 
    4709        7880 :         if (len(meter.EndUseSub) > 0) {
    4710          51 :             indexGroup += ":" + meter.EndUseSub;
    4711             :         }
    4712             : 
    4713        7880 :         return indexGroup;
    4714             :     }
    4715             : 
    4716        6069 :     void SetInternalVariableValue(EnergyPlusData &state,
    4717             :                                   OutputProcessor::VariableType const varType, // 1=integer, 2=real, 3=meter
    4718             :                                   int const keyVarIndex,                       // Array index
    4719             :                                   Real64 const SetRealVal,                     // real value to set, if type is real or meter
    4720             :                                   int const SetIntVal                          // integer value to set if type is integer
    4721             :     )
    4722             :     {
    4723             : 
    4724             :         // SUBROUTINE INFORMATION:
    4725             :         //       AUTHOR         B. Griffith
    4726             :         //       DATE WRITTEN   August 2012
    4727             :         //       MODIFIED       na
    4728             :         //       RE-ENGINEERED  na
    4729             : 
    4730             :         // PURPOSE OF THIS SUBROUTINE:
    4731             :         // This is a simple set routine for output pointers
    4732             :         // It is intended for special use to reinitializations those pointers used for EMS sensors
    4733             : 
    4734             :         // METHODOLOGY EMPLOYED:
    4735             :         // given a variable type and variable index,
    4736             :         // assign the pointers the values passed in.
    4737             : 
    4738             :         // REFERENCES:
    4739             :         // na
    4740             : 
    4741             :         // USE STATEMENTS:
    4742             :         // na
    4743             : 
    4744             :         // Locals
    4745             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    4746             : 
    4747             :         // SUBROUTINE PARAMETER DEFINITIONS:
    4748             :         // na
    4749             : 
    4750             :         // INTERFACE BLOCK SPECIFICATIONS:
    4751             :         // na
    4752             : 
    4753             :         // DERIVED TYPE DEFINITIONS:
    4754             :         // na
    4755             : 
    4756             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4757        6069 :         auto &op(state.dataOutputProcessor);
    4758             : 
    4759        6069 :         if (varType == VariableType::Integer) {
    4760          15 :             *op->IVariableTypes(keyVarIndex).VarPtr.Which = SetIntVal;
    4761        6054 :         } else if (varType == VariableType::Real) {
    4762        6009 :             *op->RVariableTypes(keyVarIndex).VarPtr.Which = SetRealVal;
    4763          45 :         } else if (varType == VariableType::Meter) {
    4764          45 :             op->EnergyMeters(keyVarIndex).CurTSValue = SetRealVal;
    4765             :         }
    4766        6069 :     }
    4767             : 
    4768             :     // returns the string corresponding to the OutputProcessor::Unit enum in brackets
    4769     1296884 :     std::string unitEnumToStringBrackets(EnergyPlus::OutputProcessor::Unit const unitIn)
    4770             :     {
    4771             :         // J.Glazer - August/September 2017
    4772     1296884 :         return " [" + unitEnumToString(unitIn) + "]";
    4773             :     }
    4774             : 
    4775             :     // returns the unit string for a DDVariableTypes item and custom string when customEMS is used
    4776      875230 :     std::string unitStringFromDDitem(EnergyPlusData &state, int const ddItemPtr // index provided for DDVariableTypes
    4777             :     )
    4778             :     {
    4779             :         // J.Glazer - August/September 2017
    4780      875230 :         OutputProcessor::Unit ddUnit = state.dataOutputProcessor->DDVariableTypes(ddItemPtr).units;
    4781      875230 :         if (ddUnit != OutputProcessor::Unit::customEMS) {
    4782      875212 :             return unitEnumToStringBrackets(ddUnit);
    4783             :         } else {
    4784          18 :             return " [" + state.dataOutputProcessor->DDVariableTypes(ddItemPtr).unitNameCustomEMS + "]";
    4785             :         }
    4786             :     }
    4787             : 
    4788             :     // returns the string corresponding to the OutputProcessor::Unit enum
    4789     1363727 :     std::string unitEnumToString(EnergyPlus::OutputProcessor::Unit const unitIn)
    4790             :     {
    4791             :         // J.Glazer - August/September 2017
    4792     1363727 :         switch (unitIn) {
    4793      619607 :         case OutputProcessor::Unit::J:
    4794      619607 :             return "J";
    4795             :             break;
    4796      249843 :         case OutputProcessor::Unit::W:
    4797      249843 :             return "W";
    4798             :             break;
    4799       87176 :         case OutputProcessor::Unit::C:
    4800       87176 :             return "C";
    4801             :             break;
    4802      101741 :         case OutputProcessor::Unit::None:
    4803      101741 :             return "";
    4804             :             break;
    4805       45021 :         case OutputProcessor::Unit::kg:
    4806       45021 :             return "kg";
    4807             :             break;
    4808       45885 :         case OutputProcessor::Unit::W_m2:
    4809       45885 :             return "W/m2";
    4810             :             break;
    4811       30533 :         case OutputProcessor::Unit::m3:
    4812       30533 :             return "m3";
    4813             :             break;
    4814       46558 :         case OutputProcessor::Unit::hr:
    4815       46558 :             return "hr";
    4816             :             break;
    4817       19673 :         case OutputProcessor::Unit::kg_s:
    4818       19673 :             return "kg/s";
    4819             :             break;
    4820       15908 :         case OutputProcessor::Unit::deg:
    4821       15908 :             return "deg";
    4822             :             break;
    4823       19454 :         case OutputProcessor::Unit::m3_s:
    4824       19454 :             return "m3/s";
    4825             :             break;
    4826       10254 :         case OutputProcessor::Unit::W_m2K:
    4827       10254 :             return "W/m2-K";
    4828             :             break;
    4829       10037 :         case OutputProcessor::Unit::kgWater_kgDryAir:
    4830       10037 :             return "kgWater/kgDryAir";
    4831             :             break;
    4832        7482 :         case OutputProcessor::Unit::Perc:
    4833        7482 :             return "%";
    4834             :             break;
    4835        7452 :         case OutputProcessor::Unit::m_s:
    4836        7452 :             return "m/s";
    4837             :             break;
    4838        4908 :         case OutputProcessor::Unit::lux:
    4839        4908 :             return "lux";
    4840             :             break;
    4841        8933 :         case OutputProcessor::Unit::kgWater_s:
    4842        8933 :             return "kgWater/s";
    4843             :             break;
    4844        2884 :         case OutputProcessor::Unit::rad:
    4845        2884 :             return "rad";
    4846             :             break;
    4847        3451 :         case OutputProcessor::Unit::Pa:
    4848        3451 :             return "Pa";
    4849             :             break;
    4850        3043 :         case OutputProcessor::Unit::J_kg:
    4851        3043 :             return "J/kg";
    4852             :             break;
    4853        4542 :         case OutputProcessor::Unit::m:
    4854        4542 :             return "m";
    4855             :             break;
    4856        3026 :         case OutputProcessor::Unit::lum_W:
    4857        3026 :             return "lum/W";
    4858             :             break;
    4859        2912 :         case OutputProcessor::Unit::kg_m3:
    4860        2912 :             return "kg/m3";
    4861             :             break;
    4862        2069 :         case OutputProcessor::Unit::L:
    4863        2069 :             return "L";
    4864             :             break;
    4865        3184 :         case OutputProcessor::Unit::ach:
    4866        3184 :             return "ach";
    4867             :             break;
    4868        1764 :         case OutputProcessor::Unit::m2:
    4869        1764 :             return "m2";
    4870             :             break;
    4871        1361 :         case OutputProcessor::Unit::deltaC:
    4872        1361 :             return "deltaC";
    4873             :             break;
    4874        1631 :         case OutputProcessor::Unit::J_kgK:
    4875        1631 :             return "J/kg-K";
    4876             :             break;
    4877         802 :         case OutputProcessor::Unit::W_W:
    4878         802 :             return "W/W";
    4879             :             break;
    4880         737 :         case OutputProcessor::Unit::clo:
    4881         737 :             return "clo";
    4882             :             break;
    4883         251 :         case OutputProcessor::Unit::W_mK:
    4884         251 :             return "W/m-K";
    4885             :             break;
    4886         612 :         case OutputProcessor::Unit::W_K:
    4887         612 :             return "W/K";
    4888             :             break;
    4889           4 :         case OutputProcessor::Unit::K_W:
    4890           4 :             return "K/W";
    4891             :             break;
    4892         313 :         case OutputProcessor::Unit::ppm:
    4893         313 :             return "ppm";
    4894             :             break;
    4895         274 :         case OutputProcessor::Unit::kg_kg:
    4896         274 :             return "kg/kg";
    4897             :             break;
    4898         106 :         case OutputProcessor::Unit::s:
    4899         106 :             return "s";
    4900             :             break;
    4901         164 :         case OutputProcessor::Unit::cd_m2:
    4902         164 :             return "cd/m2";
    4903             :             break;
    4904          33 :         case OutputProcessor::Unit::kmol_s:
    4905          33 :             return "kmol/s";
    4906             :             break;
    4907          22 :         case OutputProcessor::Unit::K_m:
    4908          22 :             return "K/m";
    4909             :             break;
    4910          14 :         case OutputProcessor::Unit::min:
    4911          14 :             return "min";
    4912             :             break;
    4913          13 :         case OutputProcessor::Unit::J_kgWater:
    4914          13 :             return "J/kgWater";
    4915             :             break;
    4916           6 :         case OutputProcessor::Unit::rev_min:
    4917           6 :             return "rev/min";
    4918             :             break;
    4919           8 :         case OutputProcessor::Unit::kg_m2s:
    4920           8 :             return "kg/m2-s";
    4921             :             break;
    4922           6 :         case OutputProcessor::Unit::J_m2:
    4923           6 :             return "J/m2";
    4924             :             break;
    4925           8 :         case OutputProcessor::Unit::A:
    4926           8 :             return "A";
    4927             :             break;
    4928           8 :         case OutputProcessor::Unit::V:
    4929           8 :             return "V";
    4930             :             break;
    4931           4 :         case OutputProcessor::Unit::W_m2C:
    4932           4 :             return "W/m2-C";
    4933             :             break;
    4934           6 :         case OutputProcessor::Unit::Ah:
    4935           6 :             return "Ah";
    4936             :             break;
    4937           4 :         case OutputProcessor::Unit::Btu_h_W:
    4938           4 :             return "Btu/h-W";
    4939             :             break;
    4940           0 :         default:
    4941           0 :             return "unknown";
    4942             :             break;
    4943             :         }
    4944             :     }
    4945             : 
    4946             :     // returns the OutputProcessor::Unit enum value when a string containing the units is provided without brackets
    4947         360 :     OutputProcessor::Unit unitStringToEnum(std::string const &unitIn)
    4948             :     {
    4949             :         // J.Glazer - August/September 2017
    4950         720 :         std::string unitUpper = UtilityRoutines::MakeUPPERCase(unitIn);
    4951         360 :         if (unitUpper == "J") {
    4952         194 :             return OutputProcessor::Unit::J;
    4953         166 :         } else if (unitUpper == "DELTAC") {
    4954          31 :             return OutputProcessor::Unit::deltaC;
    4955         135 :         } else if (unitUpper.empty()) {
    4956          78 :             return OutputProcessor::Unit::None;
    4957          57 :         } else if (unitUpper == "W") {
    4958          35 :             return OutputProcessor::Unit::W;
    4959          22 :         } else if (unitUpper == "C") {
    4960           9 :             return OutputProcessor::Unit::C;
    4961          13 :         } else if (unitUpper == "KG/S") {
    4962           0 :             return OutputProcessor::Unit::kg_s;
    4963          13 :         } else if (unitUpper == "KGWATER/KGDRYAIR") {
    4964           0 :             return OutputProcessor::Unit::kgWater_kgDryAir;
    4965          13 :         } else if (unitUpper == "PPM") {
    4966           0 :             return OutputProcessor::Unit::ppm;
    4967          13 :         } else if (unitUpper == "PA") {
    4968           0 :             return OutputProcessor::Unit::Pa;
    4969          13 :         } else if (unitUpper == "M3/S") {
    4970           0 :             return OutputProcessor::Unit::m3_s;
    4971          13 :         } else if (unitUpper == "MIN") {
    4972           0 :             return OutputProcessor::Unit::min;
    4973          13 :         } else if (unitUpper == "M3") {
    4974           0 :             return OutputProcessor::Unit::m3;
    4975          13 :         } else if (unitUpper == "KG") {
    4976           0 :             return OutputProcessor::Unit::kg;
    4977          13 :         } else if (unitUpper == "ACH") {
    4978           0 :             return OutputProcessor::Unit::ach;
    4979          13 :         } else if (unitUpper == "W/W") {
    4980           0 :             return OutputProcessor::Unit::W_W;
    4981          13 :         } else if (unitUpper == "LUX") {
    4982           0 :             return OutputProcessor::Unit::lux;
    4983          13 :         } else if (unitUpper == "LUM/W") {
    4984           0 :             return OutputProcessor::Unit::lum_W;
    4985          13 :         } else if (unitUpper == "HR") {
    4986           0 :             return OutputProcessor::Unit::hr;
    4987          13 :         } else if (unitUpper == "CD/M2") {
    4988           0 :             return OutputProcessor::Unit::cd_m2;
    4989          13 :         } else if (unitUpper == "J/KGWATER") {
    4990           0 :             return OutputProcessor::Unit::J_kgWater;
    4991          13 :         } else if (unitUpper == "M/S") {
    4992           0 :             return OutputProcessor::Unit::m_s;
    4993          13 :         } else if (unitUpper == "W/M2") {
    4994           0 :             return OutputProcessor::Unit::W_m2;
    4995          13 :         } else if (unitUpper == "M") {
    4996           0 :             return OutputProcessor::Unit::m;
    4997          13 :         } else if (unitUpper == "AH") {
    4998           0 :             return OutputProcessor::Unit::Ah;
    4999          13 :         } else if (unitUpper == "A") {
    5000           0 :             return OutputProcessor::Unit::A;
    5001          13 :         } else if (unitUpper == "V") {
    5002           0 :             return OutputProcessor::Unit::V;
    5003          13 :         } else if (unitUpper == "KMOL/S") {
    5004           0 :             return OutputProcessor::Unit::kmol_s;
    5005          13 :         } else if (unitUpper == "KG/S") {
    5006           0 :             return OutputProcessor::Unit::rev_min;
    5007          13 :         } else if (unitUpper == "W/M2-K") {
    5008           0 :             return OutputProcessor::Unit::W_m2K;
    5009          13 :         } else if (unitUpper == "J/KG") {
    5010           0 :             return OutputProcessor::Unit::J_kg;
    5011          13 :         } else if (unitUpper == "KG/KG") {
    5012           0 :             return OutputProcessor::Unit::kg_kg;
    5013          13 :         } else if (unitUpper == "%") {
    5014           0 :             return OutputProcessor::Unit::Perc;
    5015          13 :         } else if (unitUpper == "DEG") {
    5016           3 :             return OutputProcessor::Unit::deg;
    5017          10 :         } else if (unitUpper == "S") {
    5018           0 :             return OutputProcessor::Unit::s;
    5019          10 :         } else if (unitUpper == "KG/M3") {
    5020           0 :             return OutputProcessor::Unit::kg_m3;
    5021          10 :         } else if (unitUpper == "KG/M2-S") {
    5022           0 :             return OutputProcessor::Unit::kg_m2s;
    5023          10 :         } else if (unitUpper == "J/KG-K") {
    5024           0 :             return OutputProcessor::Unit::J_kgK;
    5025          10 :         } else if (unitUpper == "L") {
    5026           0 :             return OutputProcessor::Unit::L;
    5027          10 :         } else if (unitUpper == "K/M") {
    5028           0 :             return OutputProcessor::Unit::K_m;
    5029          10 :         } else if (unitUpper == "M2") {
    5030           0 :             return OutputProcessor::Unit::m2;
    5031          10 :         } else if (unitUpper == "W/M2-C") {
    5032           0 :             return OutputProcessor::Unit::W_m2C;
    5033          10 :         } else if (unitUpper == "RAD") {
    5034           0 :             return OutputProcessor::Unit::rad;
    5035          10 :         } else if (unitUpper == "J/M2") {
    5036           0 :             return OutputProcessor::Unit::J_m2;
    5037          10 :         } else if (unitUpper == "CLO") {
    5038           0 :             return OutputProcessor::Unit::clo;
    5039          10 :         } else if (unitUpper == "W/M-K") {
    5040           0 :             return OutputProcessor::Unit::W_mK;
    5041          10 :         } else if (unitUpper == "W/K") {
    5042           0 :             return OutputProcessor::Unit::W_K;
    5043          10 :         } else if (unitUpper == "K/W") {
    5044           0 :             return OutputProcessor::Unit::K_W;
    5045          10 :         } else if (unitUpper == "KGWATER/S") {
    5046           0 :             return OutputProcessor::Unit::kgWater_s;
    5047             :         } else {
    5048          10 :             return OutputProcessor::Unit::unknown;
    5049             :         }
    5050             :     }
    5051             : 
    5052             : } // namespace OutputProcessor
    5053             : 
    5054             : //==============================================================================================
    5055             : // *****************************************************************************
    5056             : // These routines are available outside the OutputProcessor Module (i.e. calling
    5057             : // routines do not have to "USE OutputProcessor".  But each of these routines
    5058             : // will use the OutputProcessor and take advantage that everything is PUBLIC
    5059             : // within the OutputProcessor.
    5060             : // *****************************************************************************
    5061             : 
    5062     5829124 : void SetupOutputVariable(EnergyPlusData &state,
    5063             :                          std::string_view const VariableName,                    // String Name of variable (with units)
    5064             :                          OutputProcessor::Unit const VariableUnit,               // Actual units corresponding to the actual variable
    5065             :                          Real64 &ActualVariable,                                 // Actual Variable, used to set up pointer
    5066             :                          OutputProcessor::SOVTimeStepType const TimeStepTypeKey, // Zone, HeatBalance=1, HVAC, System, Plant=2
    5067             :                          OutputProcessor::SOVStoreType const VariableTypeKey,    // State, Average=1, NonState, Sum=2
    5068             :                          std::string_view const KeyedValue,                      // Associated Key for this variable
    5069             :                          Optional_string_const ReportFreq,                       // Internal use -- causes reporting at this frequency
    5070             :                          Optional_string_const ResourceTypeKey,                  // Meter Resource Type (Electricity, Gas, etc)
    5071             :                          Optional_string_const EndUseKey,                        // Meter End Use Key (Lights, Heating, Cooling, etc)
    5072             :                          Optional_string_const EndUseSubKey,                     // Meter End Use Sub Key (General Lights, Task Lights, etc)
    5073             :                          Optional_string_const GroupKey,                         // Meter Super Group Key (Building, System, Plant)
    5074             :                          Optional_string_const ZoneKey,                          // Meter Zone Key (zone name)
    5075             :                          Optional_int_const ZoneMult,                            // Zone Multiplier, defaults to 1
    5076             :                          Optional_int_const ZoneListMult,                        // Zone List Multiplier, defaults to 1
    5077             :                          Optional_int_const indexGroupKey,                       // Group identifier for SQL output
    5078             :                          Optional_string_const customUnitName,                   // the custom name for the units from EMS definition of units
    5079             :                          Optional_string_const SpaceType                         // Space type (applicable for Building group only)
    5080             : )
    5081             : {
    5082             : 
    5083             :     // SUBROUTINE INFORMATION:
    5084             :     //       AUTHOR         Linda K. Lawrie
    5085             :     //       DATE WRITTEN   December 1998
    5086             :     //       MODIFIED       January 2001; Implement Meters
    5087             :     //                      August 2008; Implement SQL output
    5088             :     //       RE-ENGINEERED  na
    5089             : 
    5090             :     // PURPOSE OF THIS SUBROUTINE:
    5091             :     // This subroutine sets up the variable data structure that will be used
    5092             :     // to track values of the output variables of EnergyPlus.
    5093             : 
    5094             :     // METHODOLOGY EMPLOYED:
    5095             :     // Pointers (as pointers), pointers (as indices), and lots of other KEWL data stuff.
    5096             : 
    5097             :     // Using/Aliasing
    5098             :     using namespace OutputProcessor;
    5099             : 
    5100             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5101             :     int CV;
    5102             :     TimeStepType TimeStepType; // 1=TimeStepZone, 2=TimeStepSys
    5103             :     StoreType VariableType;    // 1=Average, 2=Sum, 3=Min/Max
    5104             :     int Loop;
    5105     5829124 :     ReportingFrequency RepFreq(ReportingFrequency::Hourly);
    5106    11658248 :     std::string ResourceType; // Will hold value of ResourceTypeKey
    5107    11658248 :     std::string EndUse;       // Will hold value of EndUseKey
    5108    11658248 :     std::string EndUseSub;    // Will hold value of EndUseSubKey
    5109    11658248 :     std::string Group;        // Will hold value of GroupKey
    5110    11658248 :     std::string zoneName;     // Will hold value of ZoneKey
    5111    11658248 :     std::string spaceType;    // Will hold value of SpaceType
    5112             :     int localIndexGroupKey;
    5113     5829124 :     auto &op(state.dataOutputProcessor);
    5114             : 
    5115     5829124 :     if (!op->OutputInitialized) InitializeOutput(state);
    5116             : 
    5117             :     // Variable name without units
    5118     5829124 :     const std::string_view VarName = VariableName;
    5119             : 
    5120             :     // Determine whether to Report or not
    5121     5829124 :     CheckReportVariable(state, KeyedValue, VarName);
    5122             : 
    5123     5829124 :     if (op->NumExtraVars == 0) {
    5124     5773926 :         op->NumExtraVars = 1;
    5125     5773926 :         op->ReportList = -1;
    5126             :     }
    5127             : 
    5128             :     // If ReportFreq present, overrides input
    5129     5829124 :     if (present(ReportFreq)) {
    5130           1 :         RepFreq = determineFrequency(state, ReportFreq);
    5131           1 :         op->NumExtraVars = 1;
    5132           1 :         op->ReportList = 0;
    5133             :     }
    5134             : 
    5135             :     // DataOutputs::OutputVariablesForSimulation is case-insensitive
    5136     5829124 :     bool const ThisOneOnTheList = DataOutputs::FindItemInVariableList(state, KeyedValue, VarName);
    5137     5829124 :     bool OnMeter = false; // True if this variable is on a meter
    5138             : 
    5139    11659904 :     for (Loop = 1; Loop <= op->NumExtraVars; ++Loop) {
    5140             : 
    5141     5830780 :         if (Loop == 1) ++op->NumOfRVariable_Setup;
    5142             : 
    5143     5830780 :         if (Loop == 1) {
    5144     5829124 :             OnMeter = false;
    5145     5829124 :             if (present(ResourceTypeKey)) {
    5146       56062 :                 ResourceType = ResourceTypeKey;
    5147       56062 :                 OnMeter = true;
    5148             :             } else {
    5149     5773062 :                 ResourceType = "";
    5150             :             }
    5151     5829124 :             if (present(EndUseKey)) {
    5152       56048 :                 EndUse = EndUseKey;
    5153       56048 :                 OnMeter = true;
    5154             :             } else {
    5155     5773076 :                 EndUse = "";
    5156             :             }
    5157     5829124 :             if (present(EndUseSubKey)) {
    5158       18135 :                 EndUseSub = EndUseSubKey;
    5159       18135 :                 OnMeter = true;
    5160             :             } else {
    5161     5810989 :                 EndUseSub = "";
    5162     5810989 :                 if (present(EndUseKey)) {
    5163       75826 :                     if (std::find(endUseCategoryNames.begin(), endUseCategoryNames.end(), UtilityRoutines::MakeUPPERCase(std::string{EndUseKey})) !=
    5164       37913 :                         endUseCategoryNames.end()) {
    5165       20935 :                         EndUseSub = "General";
    5166             :                     }
    5167             :                 }
    5168             :             }
    5169     5829124 :             if (present(GroupKey)) {
    5170       55821 :                 Group = GroupKey;
    5171       55821 :                 OnMeter = true;
    5172             :             } else {
    5173     5773303 :                 Group = "";
    5174             :             }
    5175     5829124 :             if (present(ZoneKey)) {
    5176       18825 :                 zoneName = ZoneKey;
    5177       18825 :                 OnMeter = true;
    5178             :             } else {
    5179     5810299 :                 zoneName = "";
    5180             :             }
    5181     5829124 :             if (present(SpaceType)) {
    5182        8348 :                 spaceType = SpaceType;
    5183        8348 :                 OnMeter = true;
    5184             :             } else {
    5185     5820776 :                 spaceType = "";
    5186             :             }
    5187             :         }
    5188             : 
    5189     5830780 :         TimeStepType = ValidateTimeStepType(state, TimeStepTypeKey);
    5190     5830780 :         VariableType = validateVariableType(state, VariableTypeKey);
    5191             : 
    5192     5830780 :         if (present(customUnitName)) {
    5193          10 :             AddToOutputVariableList(state, VarName, TimeStepType, VariableType, VariableType::Real, VariableUnit, customUnitName);
    5194             :         } else {
    5195     5830770 :             AddToOutputVariableList(state, VarName, TimeStepType, VariableType, VariableType::Real, VariableUnit);
    5196             :         }
    5197     5830780 :         ++op->NumTotalRVariable;
    5198             : 
    5199    11604706 :         if (!OnMeter && !ThisOneOnTheList) continue;
    5200             : 
    5201      171003 :         ++op->NumOfRVariable;
    5202      171003 :         if (Loop == 1 && VariableType == StoreType::Summed) {
    5203       94683 :             ++op->NumOfRVariable_Sum;
    5204       94683 :             if (present(ResourceTypeKey)) {
    5205       56062 :                 if (!ResourceTypeKey().empty()) ++op->NumOfRVariable_Meter;
    5206             :             }
    5207             :         }
    5208      171003 :         if (op->NumOfRVariable > op->MaxRVariable) {
    5209          59 :             ReallocateRVar(state);
    5210             :         }
    5211      171003 :         CV = op->NumOfRVariable;
    5212      171003 :         auto &thisRvar = op->RVariableTypes(CV);
    5213      171003 :         thisRvar.timeStepType = TimeStepType;
    5214      171003 :         thisRvar.storeType = VariableType;
    5215      171003 :         thisRvar.VarName = fmt::format("{}:{}", KeyedValue, VarName);
    5216      171003 :         thisRvar.VarNameOnly = VarName;
    5217      171003 :         thisRvar.VarNameOnlyUC = UtilityRoutines::MakeUPPERCase(VarName);
    5218      171003 :         thisRvar.VarNameUC = UtilityRoutines::MakeUPPERCase(thisRvar.VarName);
    5219      171003 :         thisRvar.KeyNameOnlyUC = UtilityRoutines::MakeUPPERCase(KeyedValue);
    5220      171003 :         thisRvar.units = VariableUnit;
    5221      171003 :         if (VariableUnit == OutputProcessor::Unit::customEMS) {
    5222          10 :             thisRvar.unitNameCustomEMS = customUnitName;
    5223             :         }
    5224      171003 :         AssignReportNumber(state, op->CurrentReportNumber);
    5225      227857 :         const auto IDOut = fmt::to_string(op->CurrentReportNumber);
    5226      171003 :         thisRvar.ReportID = op->CurrentReportNumber;
    5227      171003 :         auto &thisVarPtr = thisRvar.VarPtr;
    5228      171003 :         thisVarPtr.Value = 0.0;
    5229      171003 :         thisVarPtr.TSValue = 0.0;
    5230      171003 :         thisVarPtr.StoreValue = 0.0;
    5231      171003 :         thisVarPtr.NumStored = 0.0;
    5232      171003 :         thisVarPtr.MaxValue = MaxSetValue;
    5233      171003 :         thisVarPtr.maxValueDate = 0;
    5234      171003 :         thisVarPtr.MinValue = MinSetValue;
    5235      171003 :         thisVarPtr.minValueDate = 0;
    5236      171003 :         thisVarPtr.Which = &ActualVariable;
    5237      171003 :         thisVarPtr.ReportID = op->CurrentReportNumber;
    5238      171003 :         thisVarPtr.ReportIDChr = IDOut.substr(0, 15);
    5239      171003 :         thisVarPtr.storeType = VariableType;
    5240      171003 :         thisVarPtr.Stored = false;
    5241      171003 :         thisVarPtr.Report = false;
    5242      171003 :         thisVarPtr.frequency = ReportingFrequency::Hourly;
    5243      171003 :         thisVarPtr.SchedPtr = 0;
    5244      171003 :         thisVarPtr.MeterArrayPtr = 0;
    5245      171003 :         thisVarPtr.ZoneMult = 1;
    5246      171003 :         thisVarPtr.ZoneListMult = 1;
    5247      171003 :         if (present(ZoneMult) && present(ZoneListMult)) {
    5248       17986 :             thisVarPtr.ZoneMult = ZoneMult;
    5249       17986 :             thisVarPtr.ZoneListMult = ZoneListMult;
    5250             :         }
    5251             : 
    5252      171003 :         if (Loop == 1) {
    5253      169347 :             if (OnMeter) {
    5254       56062 :                 if (VariableType == StoreType::Averaged) {
    5255           0 :                     ShowSevereError(state, "Meters can only be \"Summed\" variables");
    5256           0 :                     ShowContinueError(state, fmt::format("..reference variable={}:{}", KeyedValue, VariableName));
    5257             :                 } else {
    5258       56062 :                     Unit mtrUnits = op->RVariableTypes(CV).units;
    5259       56062 :                     bool ErrorsFound = false;
    5260       56062 :                     AttachMeters(
    5261             :                         state, mtrUnits, ResourceType, EndUse, EndUseSub, Group, zoneName, spaceType, CV, thisVarPtr.MeterArrayPtr, ErrorsFound);
    5262       56062 :                     if (ErrorsFound) {
    5263           0 :                         ShowContinueError(state, fmt::format("Invalid Meter spec for variable={}:{}", KeyedValue, VariableName));
    5264           0 :                         op->ErrorsLogged = true;
    5265             :                     }
    5266             :                 }
    5267             :             }
    5268             :         }
    5269             : 
    5270      171003 :         if (op->ReportList(Loop) == -1) continue;
    5271             : 
    5272       56854 :         thisVarPtr.Report = true;
    5273             : 
    5274       56854 :         if (op->ReportList(Loop) == 0) {
    5275           1 :             thisVarPtr.frequency = RepFreq;
    5276           1 :             thisVarPtr.SchedPtr = 0;
    5277             :         } else {
    5278       56853 :             thisVarPtr.frequency = op->ReqRepVars(op->ReportList(Loop)).frequency;
    5279       56853 :             thisVarPtr.SchedPtr = op->ReqRepVars(op->ReportList(Loop)).SchedPtr;
    5280             :         }
    5281             : 
    5282       56854 :         if (thisVarPtr.Report) {
    5283       56854 :             if (present(indexGroupKey)) {
    5284           0 :                 localIndexGroupKey = indexGroupKey;
    5285             :             } else {
    5286       56854 :                 localIndexGroupKey = -999; // Unknown Group
    5287             :             }
    5288             : 
    5289       56854 :             if (thisVarPtr.SchedPtr != 0) {
    5290        6450 :                 WriteReportVariableDictionaryItem(state,
    5291             :                                                   thisVarPtr.frequency,
    5292             :                                                   thisVarPtr.storeType,
    5293             :                                                   thisVarPtr.ReportID,
    5294             :                                                   localIndexGroupKey,
    5295        4300 :                                                   std::string(sovTimeStepTypeStrings[(int)TimeStepTypeKey]),
    5296             :                                                   thisVarPtr.ReportIDChr,
    5297             :                                                   KeyedValue,
    5298             :                                                   VarName,
    5299             :                                                   thisRvar.timeStepType,
    5300             :                                                   thisRvar.units,
    5301             :                                                   thisRvar.unitNameCustomEMS,
    5302        2150 :                                                   op->ReqRepVars(op->ReportList(Loop)).SchedName);
    5303             :             } else {
    5304      164112 :                 WriteReportVariableDictionaryItem(state,
    5305             :                                                   thisVarPtr.frequency,
    5306             :                                                   thisVarPtr.storeType,
    5307             :                                                   thisVarPtr.ReportID,
    5308             :                                                   localIndexGroupKey,
    5309      109408 :                                                   std::string(sovTimeStepTypeStrings[(int)TimeStepTypeKey]),
    5310             :                                                   thisVarPtr.ReportIDChr,
    5311             :                                                   KeyedValue,
    5312             :                                                   VarName,
    5313             :                                                   thisRvar.timeStepType,
    5314             :                                                   thisRvar.units,
    5315       54704 :                                                   thisRvar.unitNameCustomEMS);
    5316             :             }
    5317             :         }
    5318             :     }
    5319     5829124 : }
    5320             : 
    5321      253776 : void SetupOutputVariable(EnergyPlusData &state,
    5322             :                          std::string_view const VariableName,                    // String Name of variable
    5323             :                          OutputProcessor::Unit const VariableUnit,               // Actual units corresponding to the actual variable
    5324             :                          int &ActualVariable,                                    // Actual Variable, used to set up pointer
    5325             :                          OutputProcessor::SOVTimeStepType const TimeStepTypeKey, // Zone, HeatBalance=1, HVAC, System, Plant=2
    5326             :                          OutputProcessor::SOVStoreType const VariableTypeKey,    // State, Average=1, NonState, Sum=2
    5327             :                          std::string_view const KeyedValue,                      // Associated Key for this variable
    5328             :                          Optional_string_const ReportFreq,                       // Internal use -- causes reporting at this freqency
    5329             :                          Optional_int_const indexGroupKey                        // Group identifier for SQL output
    5330             : )
    5331             : {
    5332             : 
    5333             :     // SUBROUTINE INFORMATION:
    5334             :     //       AUTHOR         Linda K. Lawrie
    5335             :     //       DATE WRITTEN   December 1998
    5336             :     //       MODIFIED       August 2008; Added SQL output capability
    5337             :     //       RE-ENGINEERED  na
    5338             : 
    5339             :     // PURPOSE OF THIS SUBROUTINE:
    5340             :     // This subroutine sets up the variable data structure that will be used
    5341             :     // to track values of the output variables of EnergyPlus.
    5342             : 
    5343             :     // METHODOLOGY EMPLOYED:
    5344             :     // Pointers (as pointers), pointers (as indices), and lots of other KEWL data stuff.
    5345             : 
    5346             :     // Using/Aliasing
    5347             :     using namespace OutputProcessor;
    5348             : 
    5349             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5350             :     int CV;
    5351             :     TimeStepType TimeStepType; // 1=TimeStepZone, 2=TimeStepSys
    5352             :     StoreType VariableType;    // 1=Average, 2=Sum, 3=Min/Max
    5353             :     int localIndexGroupKey;
    5354             :     int Loop;
    5355      253776 :     ReportingFrequency RepFreq(ReportingFrequency::Hourly);
    5356      253776 :     auto &op(state.dataOutputProcessor);
    5357             : 
    5358      253776 :     if (!op->OutputInitialized) InitializeOutput(state);
    5359             : 
    5360             :     // Variable name without units
    5361      253776 :     const std::string_view VarName = VariableName;
    5362             : 
    5363             :     // Determine whether to Report or not
    5364      253776 :     CheckReportVariable(state, KeyedValue, VarName);
    5365             : 
    5366      253776 :     if (op->NumExtraVars == 0) {
    5367      252206 :         op->NumExtraVars = 1;
    5368      252206 :         op->ReportList = -1;
    5369             :     }
    5370             : 
    5371             :     // If ReportFreq present, overrides input
    5372      253776 :     if (present(ReportFreq)) {
    5373           0 :         RepFreq = determineFrequency(state, ReportFreq);
    5374           0 :         op->NumExtraVars = 1;
    5375           0 :         op->ReportList = 0;
    5376             :     }
    5377             : 
    5378             :     // DataOutputs::OutputVariablesForSimulation is case-insentitive
    5379      253776 :     bool const ThisOneOnTheList = DataOutputs::FindItemInVariableList(state, KeyedValue, VarName);
    5380             : 
    5381      507572 :     for (Loop = 1; Loop <= op->NumExtraVars; ++Loop) {
    5382             : 
    5383      253796 :         if (Loop == 1) ++op->NumOfIVariable_Setup;
    5384             : 
    5385      253796 :         TimeStepType = ValidateTimeStepType(state, TimeStepTypeKey);
    5386      253796 :         VariableType = validateVariableType(state, VariableTypeKey);
    5387             : 
    5388      253796 :         AddToOutputVariableList(state, VarName, TimeStepType, VariableType, VariableType::Integer, VariableUnit);
    5389      253796 :         ++op->NumTotalIVariable;
    5390             : 
    5391      506002 :         if (!ThisOneOnTheList) continue;
    5392             : 
    5393        3829 :         ++op->NumOfIVariable;
    5394        3829 :         if (Loop == 1 && VariableType == StoreType::Summed) {
    5395         143 :             ++op->NumOfIVariable_Sum;
    5396             :         }
    5397        3829 :         if (op->NumOfIVariable > op->MaxIVariable) {
    5398         302 :             ReallocateIVar(state);
    5399             :         }
    5400             : 
    5401        3829 :         CV = op->NumOfIVariable;
    5402        3829 :         auto &thisIVar = op->IVariableTypes(CV);
    5403        3829 :         thisIVar.timeStepType = TimeStepType;
    5404        3829 :         thisIVar.storeType = VariableType;
    5405        3829 :         thisIVar.VarName = fmt::format("{}:{}", KeyedValue, VarName);
    5406        3829 :         thisIVar.VarNameOnly = VarName;
    5407        3829 :         thisIVar.VarNameOnlyUC = UtilityRoutines::MakeUPPERCase(VarName);
    5408        3829 :         thisIVar.VarNameUC = UtilityRoutines::MakeUPPERCase(thisIVar.VarName);
    5409        3829 :         thisIVar.KeyNameOnlyUC = UtilityRoutines::MakeUPPERCase(KeyedValue);
    5410        3829 :         thisIVar.units = VariableUnit;
    5411        3829 :         AssignReportNumber(state, op->CurrentReportNumber);
    5412        5419 :         const auto IDOut = fmt::to_string(op->CurrentReportNumber);
    5413        3829 :         thisIVar.ReportID = op->CurrentReportNumber;
    5414        3829 :         auto &thisVarPtr = thisIVar.VarPtr;
    5415        3829 :         thisVarPtr.Value = 0.0;
    5416        3829 :         thisVarPtr.StoreValue = 0.0;
    5417        3829 :         thisVarPtr.TSValue = 0.0;
    5418        3829 :         thisVarPtr.NumStored = 0.0;
    5419             :         //    IVariable%LastTSValue=0
    5420        3829 :         thisVarPtr.MaxValue = IMaxSetValue;
    5421        3829 :         thisVarPtr.maxValueDate = 0;
    5422        3829 :         thisVarPtr.MinValue = IMinSetValue;
    5423        3829 :         thisVarPtr.minValueDate = 0;
    5424        3829 :         thisVarPtr.Which = &ActualVariable;
    5425        3829 :         thisVarPtr.ReportID = op->CurrentReportNumber;
    5426        3829 :         thisVarPtr.ReportIDChr = IDOut.substr(0, 15);
    5427        3829 :         thisVarPtr.storeType = VariableType;
    5428        3829 :         thisVarPtr.Stored = false;
    5429        3829 :         thisVarPtr.Report = false;
    5430        3829 :         thisVarPtr.frequency = ReportingFrequency::Hourly;
    5431        3829 :         thisVarPtr.SchedPtr = 0;
    5432             : 
    5433        3829 :         if (op->ReportList(Loop) == -1) continue;
    5434             : 
    5435        1590 :         thisVarPtr.Report = true;
    5436             : 
    5437        1590 :         if (op->ReportList(Loop) == 0) {
    5438           0 :             thisVarPtr.frequency = RepFreq;
    5439           0 :             thisVarPtr.SchedPtr = 0;
    5440             :         } else {
    5441        1590 :             thisVarPtr.frequency = op->ReqRepVars(op->ReportList(Loop)).frequency;
    5442        1590 :             thisVarPtr.SchedPtr = op->ReqRepVars(op->ReportList(Loop)).SchedPtr;
    5443             :         }
    5444             : 
    5445        1590 :         if (thisVarPtr.Report) {
    5446        1590 :             if (present(indexGroupKey)) {
    5447           0 :                 localIndexGroupKey = indexGroupKey;
    5448             :             } else {
    5449        1590 :                 localIndexGroupKey = -999; // Unknown Group
    5450             :             }
    5451             : 
    5452        1590 :             if (thisVarPtr.SchedPtr != 0) {
    5453          36 :                 WriteReportVariableDictionaryItem(state,
    5454             :                                                   thisVarPtr.frequency,
    5455             :                                                   thisVarPtr.storeType,
    5456             :                                                   thisVarPtr.ReportID,
    5457             :                                                   localIndexGroupKey,
    5458          24 :                                                   std::string(sovTimeStepTypeStrings[(int)TimeStepTypeKey]),
    5459             :                                                   thisVarPtr.ReportIDChr,
    5460             :                                                   KeyedValue,
    5461             :                                                   VarName,
    5462             :                                                   thisIVar.timeStepType,
    5463             :                                                   thisIVar.units,
    5464          12 :                                                   op->ReqRepVars(op->ReportList(Loop)).SchedName);
    5465             :             } else {
    5466        4734 :                 WriteReportVariableDictionaryItem(state,
    5467             :                                                   thisVarPtr.frequency,
    5468             :                                                   thisVarPtr.storeType,
    5469             :                                                   thisVarPtr.ReportID,
    5470             :                                                   localIndexGroupKey,
    5471        3156 :                                                   std::string(sovTimeStepTypeStrings[(int)TimeStepTypeKey]),
    5472             :                                                   thisVarPtr.ReportIDChr,
    5473             :                                                   KeyedValue,
    5474             :                                                   VarName,
    5475             :                                                   thisIVar.timeStepType,
    5476        1578 :                                                   thisIVar.units);
    5477             :             }
    5478             :         }
    5479             :     }
    5480      253776 : }
    5481             : 
    5482      690474 : void UpdateDataandReport(EnergyPlusData &state, OutputProcessor::TimeStepType const t_TimeStepTypeKey) // What kind of data to update (Zone, HVAC)
    5483             : {
    5484             : 
    5485             :     // SUBROUTINE INFORMATION:
    5486             :     //       AUTHOR         Linda K. Lawrie
    5487             :     //       DATE WRITTEN   December 1998
    5488             :     //       MODIFIED       January 2001; Resolution integrated at the Zone TimeStep intervals
    5489             :     //       MODIFIED       August 2008; Added SQL output capability
    5490             :     //       RE-ENGINEERED  na
    5491             : 
    5492             :     // PURPOSE OF THIS SUBROUTINE:
    5493             :     // This subroutine writes the actual report variable (for user requested
    5494             :     // Report Variables) strings to the standard output file.
    5495             : 
    5496             :     // METHODOLOGY EMPLOYED:
    5497             :     // na
    5498             : 
    5499             :     // REFERENCES:
    5500             :     // na
    5501             : 
    5502             :     // Using/Aliasing
    5503             :     using namespace OutputProcessor;
    5504             :     using General::EncodeMonDayHrMin;
    5505             :     using ScheduleManager::GetCurrentScheduleValue;
    5506             : 
    5507             :     // Locals
    5508             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5509             : 
    5510             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5511             :     // na
    5512             : 
    5513             :     // INTERFACE BLOCK SPECIFICATIONS:
    5514             :     // na
    5515             : 
    5516             :     // DERIVED TYPE DEFINITIONS:
    5517             :     // na
    5518             : 
    5519             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5520      690474 :     bool TimePrint(true);        // True if the time needs to be printed
    5521      690474 :     bool EndTimeStepFlag(false); // True when it's the end of the Zone Time Step
    5522      690474 :     auto &op(state.dataOutputProcessor);
    5523             : 
    5524      690474 :     if (t_TimeStepTypeKey != TimeStepType::Zone && t_TimeStepTypeKey != TimeStepType::System) {
    5525           0 :         ShowFatalError(state, "Invalid reporting requested -- UpdateDataAndReport");
    5526             :     }
    5527             : 
    5528             :     // Basic record keeping and report out if "detailed"
    5529      690474 :     Real64 StartMinute = op->TimeValue.at(t_TimeStepTypeKey).CurMinute; // StartMinute for UpdateData call
    5530      690474 :     op->TimeValue.at(t_TimeStepTypeKey).CurMinute += (*op->TimeValue.at(t_TimeStepTypeKey).TimeStep) * 60.0;
    5531     1772334 :     if (t_TimeStepTypeKey == TimeStepType::System &&
    5532     1081860 :         (op->TimeValue.at(TimeStepType::System).CurMinute == op->TimeValue.at(TimeStepType::Zone).CurMinute)) {
    5533           0 :         EndTimeStepFlag = true;
    5534      690474 :     } else if (t_TimeStepTypeKey == TimeStepType::Zone) {
    5535      299088 :         EndTimeStepFlag = true;
    5536             :     } else {
    5537      391386 :         EndTimeStepFlag = false;
    5538             :     }
    5539      690474 :     Real64 MinuteNow = op->TimeValue.at(t_TimeStepTypeKey).CurMinute; // What minute it is now
    5540             : 
    5541             :     int MDHM; // Month,Day,Hour,Minute
    5542      690474 :     EncodeMonDayHrMin(MDHM, state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, int(MinuteNow));
    5543      690474 :     TimePrint = true;
    5544             : 
    5545      690474 :     Real64 rxTime = (MinuteNow - StartMinute) /
    5546      690474 :                     double(state.dataGlobal->MinutesPerTimeStep); // (MinuteNow-StartMinute)/REAL(MinutesPerTimeStep,r64) - for execution time
    5547             : 
    5548      690474 :     if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5549             :         // R and I data frames for TimeStepType::TimeStepZone
    5550        4140 :         if (t_TimeStepTypeKey == TimeStepType::Zone && !state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.rVariablesScanned()) {
    5551          21 :             state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
    5552          14 :                 ReportingFrequency::EachCall, op->RVariableTypes, op->NumOfRVariable, TimeStepType::Zone);
    5553             :         }
    5554        4140 :         if (t_TimeStepTypeKey == TimeStepType::Zone && !state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.iVariablesScanned()) {
    5555          21 :             state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
    5556          14 :                 ReportingFrequency::EachCall, op->IVariableTypes, op->NumOfIVariable, TimeStepType::Zone);
    5557             :         }
    5558             : 
    5559             :         // R and I data frames for TimeStepType::TimeStepSystem
    5560        4140 :         if (t_TimeStepTypeKey == TimeStepType::System && !state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.rVariablesScanned()) {
    5561          21 :             state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
    5562          14 :                 ReportingFrequency::EachCall, op->RVariableTypes, op->NumOfRVariable, TimeStepType::System);
    5563             :         }
    5564        4140 :         if (t_TimeStepTypeKey == TimeStepType::System && !state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.iVariablesScanned()) {
    5565          21 :             state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
    5566          14 :                 ReportingFrequency::EachCall, op->IVariableTypes, op->NumOfIVariable, TimeStepType::System);
    5567             :         }
    5568             :     }
    5569             : 
    5570      690474 :     if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5571        4140 :         if (t_TimeStepTypeKey == TimeStepType::Zone) {
    5572        8160 :             state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.newRow(
    5573        8160 :                 state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, op->TimeValue.at(TimeStepType::Zone).CurMinute);
    5574             :         }
    5575        4140 :         if (t_TimeStepTypeKey == TimeStepType::System) {
    5576             :             // TODO this was an error probably, was using TimeValue(1)
    5577       12540 :             state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.newRow(
    5578       12540 :                 state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, op->TimeValue.at(TimeStepType::System).CurMinute);
    5579             :         }
    5580             :     }
    5581             : 
    5582             :     // Main "Record Keeping" Loops for R and I variables
    5583   142459923 :     for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    5584   141769449 :         if (op->RVariableTypes(Loop).timeStepType != t_TimeStepTypeKey) continue;
    5585             : 
    5586             :         // Act on the RVariables variable
    5587    73980952 :         auto &rVar(op->RVariableTypes(Loop).VarPtr);
    5588    73980952 :         rVar.Stored = true;
    5589    73980952 :         if (rVar.storeType == StoreType::Averaged) {
    5590    36252282 :             Real64 CurVal = (*rVar.Which) * rxTime;
    5591             :             //        CALL SetMinMax(RVar%Which,MDHM,RVar%MaxValue,RVar%maxValueDate,RVar%MinValue,RVar%minValueDate)
    5592    36252282 :             if ((*rVar.Which) > rVar.MaxValue) {
    5593     2450717 :                 rVar.MaxValue = (*rVar.Which);
    5594     2450717 :                 rVar.maxValueDate = MDHM;
    5595             :             }
    5596    36252282 :             if ((*rVar.Which) < rVar.MinValue) {
    5597     1628594 :                 rVar.MinValue = (*rVar.Which);
    5598     1628594 :                 rVar.minValueDate = MDHM;
    5599             :             }
    5600    36252282 :             rVar.TSValue += CurVal;
    5601    36252282 :             rVar.EITSValue = rVar.TSValue; // CR - 8481 fix - 09/06/2011
    5602             :         } else {
    5603             :             //        CurVal=RVar%Which
    5604    37728670 :             if ((*rVar.Which) > rVar.MaxValue) {
    5605     1353425 :                 rVar.MaxValue = (*rVar.Which);
    5606     1353425 :                 rVar.maxValueDate = MDHM;
    5607             :             }
    5608    37728670 :             if ((*rVar.Which) < rVar.MinValue) {
    5609      464896 :                 rVar.MinValue = (*rVar.Which);
    5610      464896 :                 rVar.minValueDate = MDHM;
    5611             :             }
    5612    37728670 :             rVar.TSValue += (*rVar.Which);
    5613    37728670 :             rVar.EITSValue = rVar.TSValue; // CR - 8481 fix - 09/06/2011
    5614             :         }
    5615             : 
    5616             :         // End of "record keeping"  Report if applicable
    5617    73980952 :         if (!rVar.Report) continue;
    5618    35194679 :         bool ReportNow = true;
    5619    35194679 :         if (rVar.SchedPtr > 0) ReportNow = (GetCurrentScheduleValue(state, rVar.SchedPtr) != 0.0); // SetReportNow(RVar%SchedPtr)
    5620    35194679 :         if (!ReportNow) continue;
    5621    35049871 :         rVar.tsStored = true;
    5622    35049871 :         if (!rVar.thisTSStored) {
    5623    27059240 :             ++rVar.thisTSCount;
    5624    27059240 :             rVar.thisTSStored = true;
    5625             :         }
    5626             : 
    5627    35049871 :         if (rVar.frequency == ReportingFrequency::EachCall) {
    5628      554032 :             if (TimePrint) {
    5629       23533 :                 if (op->LHourP != state.dataGlobal->HourOfDay || std::abs(op->LStartMin - StartMinute) > 0.001 ||
    5630        2699 :                     std::abs(op->LEndMin - op->TimeValue.at(t_TimeStepTypeKey).CurMinute) > 0.001) {
    5631       18135 :                     int CurDayType = state.dataEnvrn->DayOfWeek;
    5632       18135 :                     if (state.dataEnvrn->HolidayIndex > 0) {
    5633       18135 :                         CurDayType = state.dataEnvrn->HolidayIndex;
    5634             :                     }
    5635      163215 :                     WriteTimeStampFormatData(state,
    5636             :                                              state.files.eso,
    5637             :                                              ReportingFrequency::EachCall,
    5638       18135 :                                              op->TimeStepStampReportNbr,
    5639       18135 :                                              op->TimeStepStampReportChr,
    5640       18135 :                                              state.dataGlobal->DayOfSimChr,
    5641             :                                              true,
    5642       18135 :                                              state.dataEnvrn->Month,
    5643       18135 :                                              state.dataEnvrn->DayOfMonth,
    5644       18135 :                                              state.dataGlobal->HourOfDay,
    5645       18135 :                                              op->TimeValue.at(t_TimeStepTypeKey).CurMinute,
    5646             :                                              StartMinute,
    5647       18135 :                                              state.dataEnvrn->DSTIndicator,
    5648       18135 :                                              ScheduleManager::dayTypeNames[CurDayType]);
    5649       18135 :                     op->LHourP = state.dataGlobal->HourOfDay;
    5650       18135 :                     op->LStartMin = StartMinute;
    5651       18135 :                     op->LEndMin = op->TimeValue.at(t_TimeStepTypeKey).CurMinute;
    5652             :                 }
    5653       20834 :                 TimePrint = false;
    5654             :             }
    5655      554032 :             WriteNumericData(state, rVar.ReportID, rVar.ReportIDChr, *rVar.Which);
    5656      554032 :             ++state.dataGlobal->StdOutputRecordCount;
    5657             : 
    5658      554032 :             if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5659        7810 :                 if (t_TimeStepTypeKey == TimeStepType::Zone) {
    5660         384 :                     state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.pushVariableValue(rVar.ReportID, *rVar.Which);
    5661             :                 }
    5662        7810 :                 if (t_TimeStepTypeKey == TimeStepType::System) {
    5663        7426 :                     state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.pushVariableValue(rVar.ReportID, *rVar.Which);
    5664             :                 }
    5665             :             }
    5666             :         }
    5667             :     }
    5668             : 
    5669     3601187 :     for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    5670     2910713 :         if (op->IVariableTypes(Loop).timeStepType != t_TimeStepTypeKey) continue;
    5671             : 
    5672             :         // Act on the IVariables variable
    5673     1328639 :         auto &iVar(op->IVariableTypes(Loop).VarPtr);
    5674     1328639 :         iVar.Stored = true;
    5675             :         //      ICurVal=IVar%Which
    5676     1328639 :         if (iVar.storeType == StoreType::Averaged) {
    5677     1243022 :             Real64 ICurVal = (*iVar.Which) * rxTime;
    5678     1243022 :             iVar.TSValue += ICurVal;
    5679     1243022 :             iVar.EITSValue = iVar.TSValue; // CR - 8481 fix - 09/06/2011
    5680     1243022 :             if (nint(ICurVal) > iVar.MaxValue) {
    5681        4993 :                 iVar.MaxValue = nint(ICurVal); // Record keeping for date and time go here too
    5682        4993 :                 iVar.maxValueDate = MDHM;      //+ TimeValue.at(t_TimeStepTypeKey)%TimeStep
    5683             :             }
    5684     1243022 :             if (nint(ICurVal) < iVar.MinValue) {
    5685        4470 :                 iVar.MinValue = nint(ICurVal);
    5686        4470 :                 iVar.minValueDate = MDHM; //+ TimeValue.at(t_TimeStepTypeKey)%TimeStep
    5687             :             }
    5688             :         } else {
    5689       85617 :             if ((*iVar.Which) > iVar.MaxValue) {
    5690         315 :                 iVar.MaxValue = (*iVar.Which); // Record keeping for date and time go here too
    5691         315 :                 iVar.maxValueDate = MDHM;      //+ TimeValue(TimeStepType)%TimeStep
    5692             :             }
    5693       85617 :             if ((*iVar.Which) < iVar.MinValue) {
    5694         197 :                 iVar.MinValue = (*iVar.Which);
    5695         197 :                 iVar.minValueDate = MDHM; //+ TimeValue(TimeStepType)%TimeStep
    5696             :             }
    5697       85617 :             iVar.TSValue += (*iVar.Which);
    5698       85617 :             iVar.EITSValue = iVar.TSValue; // CR - 8481 fix - 09/06/2011
    5699             :         }
    5700             : 
    5701     1328639 :         if (!iVar.Report) continue;
    5702      895439 :         bool ReportNow = true;
    5703      895439 :         if (iVar.SchedPtr > 0) ReportNow = (GetCurrentScheduleValue(state, iVar.SchedPtr) != 0.0); // SetReportNow(IVar%SchedPtr)
    5704      895439 :         if (!ReportNow) continue;
    5705      895439 :         iVar.tsStored = true;
    5706      895439 :         if (!iVar.thisTSStored) {
    5707      666144 :             ++iVar.thisTSCount;
    5708      666144 :             iVar.thisTSStored = true;
    5709             :         }
    5710             : 
    5711      895439 :         if (iVar.frequency == ReportingFrequency::EachCall) {
    5712        7320 :             if (TimePrint) {
    5713           0 :                 if (op->LHourP != state.dataGlobal->HourOfDay || std::abs(op->LStartMin - StartMinute) > 0.001 ||
    5714           0 :                     std::abs(op->LEndMin - op->TimeValue.at(t_TimeStepTypeKey).CurMinute) > 0.001) {
    5715           0 :                     int CurDayType = state.dataEnvrn->DayOfWeek;
    5716           0 :                     if (state.dataEnvrn->HolidayIndex > 0) {
    5717           0 :                         CurDayType = state.dataEnvrn->HolidayIndex;
    5718             :                     }
    5719           0 :                     WriteTimeStampFormatData(state,
    5720             :                                              state.files.eso,
    5721             :                                              ReportingFrequency::EachCall,
    5722           0 :                                              op->TimeStepStampReportNbr,
    5723           0 :                                              op->TimeStepStampReportChr,
    5724           0 :                                              state.dataGlobal->DayOfSimChr,
    5725             :                                              true,
    5726           0 :                                              state.dataEnvrn->Month,
    5727           0 :                                              state.dataEnvrn->DayOfMonth,
    5728           0 :                                              state.dataGlobal->HourOfDay,
    5729           0 :                                              op->TimeValue.at(t_TimeStepTypeKey).CurMinute,
    5730             :                                              StartMinute,
    5731           0 :                                              state.dataEnvrn->DSTIndicator,
    5732           0 :                                              ScheduleManager::dayTypeNames[CurDayType]);
    5733           0 :                     op->LHourP = state.dataGlobal->HourOfDay;
    5734           0 :                     op->LStartMin = StartMinute;
    5735           0 :                     op->LEndMin = op->TimeValue.at(t_TimeStepTypeKey).CurMinute;
    5736             :                 }
    5737           0 :                 TimePrint = false;
    5738             :             }
    5739             :             // only time integer vars actual report as integer only is "detailed"
    5740        7320 :             WriteNumericData(state, iVar.ReportID, iVar.ReportIDChr, *iVar.Which);
    5741        7320 :             ++state.dataGlobal->StdOutputRecordCount;
    5742             : 
    5743        7320 :             if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5744         737 :                 if (t_TimeStepTypeKey == TimeStepType::Zone) {
    5745           0 :                     state.dataResultsFramework->resultsFramework->RIDetailedZoneTSData.pushVariableValue(iVar.ReportID, *iVar.Which);
    5746             :                 }
    5747         737 :                 if (t_TimeStepTypeKey == TimeStepType::System) {
    5748         737 :                     state.dataResultsFramework->resultsFramework->RIDetailedHVACTSData.pushVariableValue(iVar.ReportID, *iVar.Which);
    5749             :                 }
    5750             :             }
    5751             :         }
    5752             :     }
    5753             : 
    5754     1378541 :     if (t_TimeStepTypeKey == TimeStepType::System) return; // All other stuff happens at the "zone" time step call to this routine.
    5755             : 
    5756             :     // TimeStep Block (Report on Zone TimeStep)
    5757             : 
    5758      299088 :     if (EndTimeStepFlag) {
    5759      299088 :         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5760        1632 :             if (!state.dataResultsFramework->resultsFramework->RITimestepTSData.rVariablesScanned()) {
    5761          21 :                 state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
    5762          14 :                     ReportingFrequency::TimeStep, op->RVariableTypes, op->NumOfRVariable);
    5763             :             }
    5764        1632 :             if (!state.dataResultsFramework->resultsFramework->RITimestepTSData.iVariablesScanned()) {
    5765          21 :                 state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
    5766          14 :                     ReportingFrequency::TimeStep, op->IVariableTypes, op->NumOfIVariable);
    5767             :             }
    5768        8160 :             state.dataResultsFramework->resultsFramework->RITimestepTSData.newRow(
    5769        8160 :                 state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, op->TimeValue.at(TimeStepType::Zone).CurMinute);
    5770             :         }
    5771             : 
    5772      897264 :         for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
    5773   117964992 :             for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    5774   117366816 :                 if (op->RVariableTypes(Loop).timeStepType != thisTimeStepType) continue;
    5775    58683408 :                 auto &rVar(op->RVariableTypes(Loop).VarPtr);
    5776             :                 // Update meters on the TimeStep  (Zone)
    5777    58683408 :                 if (rVar.MeterArrayPtr != 0 && !state.dataOutputProcessor->MeterValue.empty()) {
    5778    20327808 :                     Real64 TimeStepValue = rVar.TSValue * rVar.ZoneMult * rVar.ZoneListMult;
    5779   122677296 :                     for (int i = 1; i <= op->VarMeterArrays(rVar.MeterArrayPtr).NumOnMeters; i++) {
    5780   102349488 :                         int index = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(i);
    5781   102349488 :                         state.dataOutputProcessor->MeterValue(index) += TimeStepValue;
    5782             :                     }
    5783    21878208 :                     for (int i = 1; i <= op->VarMeterArrays(rVar.MeterArrayPtr).NumOnCustomMeters; i++) {
    5784     1550400 :                         int index = op->VarMeterArrays(rVar.MeterArrayPtr).OnCustomMeters(i);
    5785     1550400 :                         state.dataOutputProcessor->MeterValue(index) += TimeStepValue;
    5786             :                     }
    5787             :                 }
    5788             : 
    5789    58683408 :                 bool ReportNow = true;
    5790    58683408 :                 if (rVar.SchedPtr > 0) ReportNow = (GetCurrentScheduleValue(state, rVar.SchedPtr) != 0.0); // SetReportNow(RVar%SchedPtr)
    5791    58683408 :                 if (!ReportNow || !rVar.Report) {
    5792    31624168 :                     rVar.TSValue = 0.0;
    5793             :                 }
    5794             :                 //        IF (RVar%StoreType == AveragedVar) THEN
    5795             :                 //          RVar%Value=RVar%Value+RVar%TSValue/NumOfTimeStepInHour
    5796             :                 //        ELSE
    5797    58683408 :                 rVar.Value += rVar.TSValue;
    5798             :                 //        ENDIF
    5799             : 
    5800    58683408 :                 if (!ReportNow || !rVar.Report) continue;
    5801             : 
    5802    27059240 :                 if (rVar.frequency == ReportingFrequency::TimeStep) {
    5803     6273024 :                     if (TimePrint) {
    5804      103214 :                         if (op->LHourP != state.dataGlobal->HourOfDay || std::abs(op->LStartMin - StartMinute) > 0.001 ||
    5805          62 :                             std::abs(op->LEndMin - op->TimeValue.at(thisTimeStepType).CurMinute) > 0.001) {
    5806      103090 :                             int CurDayType = state.dataEnvrn->DayOfWeek;
    5807      103090 :                             if (state.dataEnvrn->HolidayIndex > 0) {
    5808       99154 :                                 CurDayType = state.dataEnvrn->HolidayIndex;
    5809             :                             }
    5810      927810 :                             WriteTimeStampFormatData(state,
    5811             :                                                      state.files.eso,
    5812             :                                                      ReportingFrequency::EachCall,
    5813      103090 :                                                      op->TimeStepStampReportNbr,
    5814      103090 :                                                      op->TimeStepStampReportChr,
    5815      103090 :                                                      state.dataGlobal->DayOfSimChr,
    5816             :                                                      true,
    5817      103090 :                                                      state.dataEnvrn->Month,
    5818      103090 :                                                      state.dataEnvrn->DayOfMonth,
    5819      103090 :                                                      state.dataGlobal->HourOfDay,
    5820      103090 :                                                      op->TimeValue.at(thisTimeStepType).CurMinute,
    5821             :                                                      StartMinute,
    5822      103090 :                                                      state.dataEnvrn->DSTIndicator,
    5823      103090 :                                                      ScheduleManager::dayTypeNames[CurDayType]);
    5824      103090 :                             op->LHourP = state.dataGlobal->HourOfDay;
    5825      103090 :                             op->LStartMin = StartMinute;
    5826      103090 :                             op->LEndMin = op->TimeValue.at(thisTimeStepType).CurMinute;
    5827             :                         }
    5828      103152 :                         TimePrint = false;
    5829             :                     }
    5830             : 
    5831     6273024 :                     WriteNumericData(state, rVar.ReportID, rVar.ReportIDChr, rVar.TSValue);
    5832     6273024 :                     ++state.dataGlobal->StdOutputRecordCount;
    5833             : 
    5834     6273024 :                     if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5835           0 :                         state.dataResultsFramework->resultsFramework->RITimestepTSData.pushVariableValue(rVar.ReportID, rVar.TSValue);
    5836             :                     }
    5837             :                 }
    5838    27059240 :                 rVar.TSValue = 0.0;
    5839    27059240 :                 rVar.thisTSStored = false;
    5840             :             } // Number of R Variables
    5841             : 
    5842     2796864 :             for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    5843     2198688 :                 if (op->IVariableTypes(Loop).timeStepType != thisTimeStepType) continue;
    5844     1099344 :                 auto &iVar(op->IVariableTypes(Loop).VarPtr);
    5845     1099344 :                 bool ReportNow = true;
    5846     1099344 :                 if (iVar.SchedPtr > 0) ReportNow = (GetCurrentScheduleValue(state, iVar.SchedPtr) != 0.0); // SetReportNow(IVar%SchedPtr)
    5847     1099344 :                 if (!ReportNow) {
    5848           0 :                     iVar.TSValue = 0.0;
    5849             :                 }
    5850             :                 //        IF (IVar%StoreType == AveragedVar) THEN
    5851             :                 //          IVar%Value=IVar%Value+REAL(IVar%TSValue,r64)/REAL(NumOfTimeStepInHour,r64)
    5852             :                 //        ELSE
    5853     1099344 :                 iVar.Value += iVar.TSValue;
    5854             :                 //        ENDIF
    5855             : 
    5856     1099344 :                 if (!ReportNow || !iVar.Report) continue;
    5857             : 
    5858      666144 :                 if (iVar.frequency == ReportingFrequency::TimeStep) {
    5859      279264 :                     if (TimePrint) {
    5860         288 :                         if (op->LHourP != state.dataGlobal->HourOfDay || std::abs(op->LStartMin - StartMinute) > 0.001 ||
    5861           0 :                             std::abs(op->LEndMin - op->TimeValue.at(thisTimeStepType).CurMinute) > 0.001) {
    5862         288 :                             int CurDayType = state.dataEnvrn->DayOfWeek;
    5863         288 :                             if (state.dataEnvrn->HolidayIndex > 0) {
    5864         288 :                                 CurDayType = state.dataEnvrn->HolidayIndex;
    5865             :                             }
    5866        2592 :                             WriteTimeStampFormatData(state,
    5867             :                                                      state.files.eso,
    5868             :                                                      ReportingFrequency::EachCall,
    5869         288 :                                                      op->TimeStepStampReportNbr,
    5870         288 :                                                      op->TimeStepStampReportChr,
    5871         288 :                                                      state.dataGlobal->DayOfSimChr,
    5872             :                                                      true,
    5873         288 :                                                      state.dataEnvrn->Month,
    5874         288 :                                                      state.dataEnvrn->DayOfMonth,
    5875         288 :                                                      state.dataGlobal->HourOfDay,
    5876         288 :                                                      op->TimeValue.at(thisTimeStepType).CurMinute,
    5877             :                                                      StartMinute,
    5878         288 :                                                      state.dataEnvrn->DSTIndicator,
    5879         288 :                                                      ScheduleManager::dayTypeNames[CurDayType]);
    5880         288 :                             op->LHourP = state.dataGlobal->HourOfDay;
    5881         288 :                             op->LStartMin = StartMinute;
    5882         288 :                             op->LEndMin = op->TimeValue.at(thisTimeStepType).CurMinute;
    5883             :                         }
    5884         288 :                         TimePrint = false;
    5885             :                     }
    5886             : 
    5887      279264 :                     WriteNumericData(state, iVar.ReportID, iVar.ReportIDChr, iVar.TSValue);
    5888      279264 :                     ++state.dataGlobal->StdOutputRecordCount;
    5889             : 
    5890      279264 :                     if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5891           0 :                         state.dataResultsFramework->resultsFramework->RITimestepTSData.pushVariableValue(iVar.ReportID, iVar.TSValue);
    5892             :                     }
    5893             :                 }
    5894      666144 :                 iVar.TSValue = 0.0;
    5895      666144 :                 iVar.thisTSStored = false;
    5896             :             } // Number of I Variables
    5897             :         }     // Index Type (Zone or HVAC)
    5898             : 
    5899      299088 :         UpdateMeters(state, MDHM);
    5900             : 
    5901      299088 :         ReportTSMeters(state, StartMinute, op->TimeValue.at(TimeStepType::Zone).CurMinute, TimePrint, TimePrint);
    5902             : 
    5903             :     } // TimeStep Block
    5904             : 
    5905             :     // Hour Block
    5906      299088 :     if (state.dataGlobal->EndHourFlag) {
    5907       57768 :         if (op->TrackingHourlyVariables) {
    5908       40272 :             int CurDayType = state.dataEnvrn->DayOfWeek;
    5909       40272 :             if (state.dataEnvrn->HolidayIndex > 0) {
    5910       22584 :                 CurDayType = state.dataEnvrn->HolidayIndex;
    5911             :             }
    5912      322176 :             WriteTimeStampFormatData(state,
    5913             :                                      state.files.eso,
    5914             :                                      ReportingFrequency::Hourly,
    5915       40272 :                                      op->TimeStepStampReportNbr,
    5916       40272 :                                      op->TimeStepStampReportChr,
    5917       40272 :                                      state.dataGlobal->DayOfSimChr,
    5918             :                                      true,
    5919       40272 :                                      state.dataEnvrn->Month,
    5920       40272 :                                      state.dataEnvrn->DayOfMonth,
    5921       40272 :                                      state.dataGlobal->HourOfDay,
    5922             :                                      _,
    5923             :                                      _,
    5924       40272 :                                      state.dataEnvrn->DSTIndicator,
    5925       40272 :                                      ScheduleManager::dayTypeNames[CurDayType]);
    5926       40272 :             TimePrint = false;
    5927             :         }
    5928             : 
    5929       57768 :         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5930         336 :             if (!state.dataResultsFramework->resultsFramework->RIHourlyTSData.rVariablesScanned()) {
    5931          21 :                 state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
    5932          14 :                     ReportingFrequency::Hourly, op->RVariableTypes, op->NumOfRVariable);
    5933             :             }
    5934         336 :             if (!state.dataResultsFramework->resultsFramework->RIHourlyTSData.iVariablesScanned()) {
    5935          21 :                 state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
    5936          14 :                     ReportingFrequency::Hourly, op->IVariableTypes, op->NumOfIVariable);
    5937             :             }
    5938        1344 :             state.dataResultsFramework->resultsFramework->RIHourlyTSData.newRow(
    5939        1008 :                 state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    5940             :         }
    5941             : 
    5942      173304 :         for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
    5943      115536 :             op->TimeValue.at(thisTimeStepType).CurMinute = 0.0;
    5944    23999904 :             for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    5945    23884368 :                 if (op->RVariableTypes(Loop).timeStepType != thisTimeStepType) continue;
    5946    11942184 :                 auto &rVar(op->RVariableTypes(Loop).VarPtr);
    5947             :                 //        ReportNow=.TRUE.
    5948             :                 //        IF (RVar%SchedPtr > 0) &
    5949             :                 //          ReportNow=(GetCurrentScheduleValue(state, RVar%SchedPtr) /= 0.0)  !SetReportNow(RVar%SchedPtr)
    5950             : 
    5951             :                 //        IF (ReportNow) THEN
    5952    11942184 :                 if (rVar.tsStored) {
    5953     5132774 :                     if (rVar.storeType == StoreType::Averaged) {
    5954     4602854 :                         rVar.Value /= double(rVar.thisTSCount);
    5955             :                     }
    5956     5132774 :                     if (rVar.Report && rVar.frequency == ReportingFrequency::Hourly && rVar.Stored) {
    5957     2703140 :                         WriteNumericData(state, rVar.ReportID, rVar.ReportIDChr, rVar.Value);
    5958     2703140 :                         ++state.dataGlobal->StdOutputRecordCount;
    5959     2703140 :                         rVar.Stored = false;
    5960             :                         // add time series value for hourly to data store
    5961     2703140 :                         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5962       14556 :                             state.dataResultsFramework->resultsFramework->RIHourlyTSData.pushVariableValue(rVar.ReportID, rVar.Value);
    5963             :                         }
    5964             :                     }
    5965     5132774 :                     rVar.StoreValue += rVar.Value;
    5966     5132774 :                     ++rVar.NumStored;
    5967             :                 }
    5968    11942184 :                 rVar.tsStored = false;
    5969    11942184 :                 rVar.thisTSStored = false;
    5970    11942184 :                 rVar.thisTSCount = 0;
    5971    11942184 :                 rVar.Value = 0.0;
    5972             :             } // Number of R Variables
    5973             : 
    5974      562944 :             for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    5975      447408 :                 if (op->IVariableTypes(Loop).timeStepType != thisTimeStepType) continue;
    5976      223704 :                 auto &iVar(op->IVariableTypes(Loop).VarPtr);
    5977             :                 //        ReportNow=.TRUE.
    5978             :                 //        IF (IVar%SchedPtr > 0) &
    5979             :                 //          ReportNow=(GetCurrentScheduleValue(state, IVar%SchedPtr) /= 0.0)  !SetReportNow(IVar%SchedPtr)
    5980             :                 //        IF (ReportNow) THEN
    5981      223704 :                 if (iVar.tsStored) {
    5982      116232 :                     if (iVar.storeType == StoreType::Averaged) {
    5983      106872 :                         iVar.Value /= double(iVar.thisTSCount);
    5984             :                     }
    5985      116232 :                     if (iVar.Report && iVar.frequency == ReportingFrequency::Hourly && iVar.Stored) {
    5986       51336 :                         WriteNumericData(state, iVar.ReportID, iVar.ReportIDChr, iVar.Value);
    5987       51336 :                         ++state.dataGlobal->StdOutputRecordCount;
    5988       51336 :                         iVar.Stored = false;
    5989       51336 :                         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    5990        1152 :                             state.dataResultsFramework->resultsFramework->RIHourlyTSData.pushVariableValue(iVar.ReportID, iVar.Value);
    5991             :                         }
    5992             :                     }
    5993      116232 :                     iVar.StoreValue += iVar.Value;
    5994      116232 :                     ++iVar.NumStored;
    5995             :                 }
    5996      223704 :                 iVar.tsStored = false;
    5997      223704 :                 iVar.thisTSStored = false;
    5998      223704 :                 iVar.thisTSCount = 0;
    5999      223704 :                 iVar.Value = 0.0;
    6000             :             } // Number of I Variables
    6001             :         }     // thisTimeStepType (Zone or HVAC)
    6002             : 
    6003       57768 :         ReportHRMeters(state, TimePrint);
    6004             : 
    6005             :     } // Hour Block
    6006             : 
    6007      299088 :     if (!state.dataGlobal->EndHourFlag) return;
    6008             : 
    6009             :     // Day Block
    6010       57768 :     if (state.dataGlobal->EndDayFlag) {
    6011        2407 :         if (op->TrackingDailyVariables) {
    6012          94 :             int CurDayType = state.dataEnvrn->DayOfWeek;
    6013          94 :             if (state.dataEnvrn->HolidayIndex > 0) {
    6014          90 :                 CurDayType = state.dataEnvrn->HolidayIndex;
    6015             :             }
    6016         658 :             WriteTimeStampFormatData(state,
    6017             :                                      state.files.eso,
    6018             :                                      ReportingFrequency::Daily,
    6019          94 :                                      op->DailyStampReportNbr,
    6020          94 :                                      op->DailyStampReportChr,
    6021          94 :                                      state.dataGlobal->DayOfSimChr,
    6022             :                                      true,
    6023          94 :                                      state.dataEnvrn->Month,
    6024          94 :                                      state.dataEnvrn->DayOfMonth,
    6025             :                                      _,
    6026             :                                      _,
    6027             :                                      _,
    6028          94 :                                      state.dataEnvrn->DSTIndicator,
    6029          94 :                                      ScheduleManager::dayTypeNames[CurDayType]);
    6030          94 :             TimePrint = false;
    6031             :         }
    6032        2407 :         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    6033          14 :             if (!state.dataResultsFramework->resultsFramework->RIDailyTSData.rVariablesScanned()) {
    6034          21 :                 state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
    6035          14 :                     ReportingFrequency::Daily, op->RVariableTypes, op->NumOfRVariable);
    6036             :             }
    6037          14 :             if (!state.dataResultsFramework->resultsFramework->RIDailyTSData.iVariablesScanned()) {
    6038          21 :                 state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
    6039          14 :                     ReportingFrequency::Daily, op->IVariableTypes, op->NumOfIVariable);
    6040             :             }
    6041          56 :             state.dataResultsFramework->resultsFramework->RIDailyTSData.newRow(
    6042          42 :                 state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    6043             :         }
    6044             : 
    6045        2407 :         op->NumHoursInMonth += 24;
    6046        7221 :         for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
    6047      999996 :             for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    6048      995182 :                 if (op->RVariableTypes(Loop).timeStepType == thisTimeStepType) {
    6049      497591 :                     WriteRealVariableOutput(state, op->RVariableTypes(Loop).VarPtr, ReportingFrequency::Daily);
    6050             :                 }
    6051             :             } // Number of R Variables
    6052             : 
    6053       23456 :             for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    6054       18642 :                 if (op->IVariableTypes(Loop).timeStepType == thisTimeStepType) {
    6055        9321 :                     WriteIntegerVariableOutput(state, op->IVariableTypes(Loop).VarPtr, ReportingFrequency::Daily);
    6056             :                 }
    6057             :             } // Number of I Variables
    6058             :         }     // thisTimeStepType (Zone or HVAC)
    6059             : 
    6060        2407 :         ReportDYMeters(state, TimePrint);
    6061             : 
    6062             :     } // Day Block
    6063             : 
    6064             :     // Only continue if EndDayFlag is set
    6065       57768 :     if (!state.dataGlobal->EndDayFlag) return;
    6066             : 
    6067             :     // Month Block
    6068        2407 :     if (state.dataEnvrn->EndMonthFlag || state.dataGlobal->EndEnvrnFlag) {
    6069        1669 :         if (op->TrackingMonthlyVariables) {
    6070        1135 :             WriteTimeStampFormatData(state,
    6071             :                                      state.files.eso,
    6072             :                                      ReportingFrequency::Monthly,
    6073         227 :                                      op->MonthlyStampReportNbr,
    6074         227 :                                      op->MonthlyStampReportChr,
    6075         227 :                                      state.dataGlobal->DayOfSimChr,
    6076             :                                      true,
    6077         227 :                                      state.dataEnvrn->Month);
    6078         227 :             TimePrint = false;
    6079             :         }
    6080             : 
    6081        1669 :         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    6082          14 :             if (!state.dataResultsFramework->resultsFramework->RIMonthlyTSData.rVariablesScanned()) {
    6083          21 :                 state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
    6084          14 :                     ReportingFrequency::Monthly, op->RVariableTypes, op->NumOfRVariable);
    6085             :             }
    6086          14 :             if (!state.dataResultsFramework->resultsFramework->RIMonthlyTSData.iVariablesScanned()) {
    6087          21 :                 state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
    6088          14 :                     ReportingFrequency::Monthly, op->IVariableTypes, op->NumOfIVariable);
    6089             :             }
    6090          56 :             state.dataResultsFramework->resultsFramework->RIMonthlyTSData.newRow(
    6091          42 :                 state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    6092             :         }
    6093             : 
    6094        1669 :         op->NumHoursInSim += op->NumHoursInMonth;
    6095        1669 :         state.dataEnvrn->EndMonthFlag = false;
    6096        5007 :         for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
    6097      812434 :             for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    6098      809096 :                 if (op->RVariableTypes(Loop).timeStepType == thisTimeStepType) {
    6099      404548 :                     WriteRealVariableOutput(state, op->RVariableTypes(Loop).VarPtr, ReportingFrequency::Monthly);
    6100             :                 }
    6101             :             } // Number of R Variables
    6102             : 
    6103       20518 :             for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    6104       17180 :                 if (op->IVariableTypes(Loop).timeStepType == thisTimeStepType) {
    6105        8590 :                     WriteIntegerVariableOutput(state, op->IVariableTypes(Loop).VarPtr, ReportingFrequency::Monthly);
    6106             :                 }
    6107             :             } // Number of I Variables
    6108             :         }     // thisTimeStepType (Zone, HVAC)
    6109             : 
    6110        1669 :         ReportMNMeters(state, TimePrint);
    6111             : 
    6112        1669 :         op->NumHoursInMonth = 0;
    6113             :     } // Month Block
    6114             : 
    6115             :     // Sim/Environment Block
    6116        2407 :     if (state.dataGlobal->EndEnvrnFlag) {
    6117        1645 :         if (op->TrackingRunPeriodVariables) {
    6118         340 :             WriteTimeStampFormatData(state,
    6119             :                                      state.files.eso,
    6120             :                                      ReportingFrequency::Simulation,
    6121          85 :                                      op->RunPeriodStampReportNbr,
    6122          85 :                                      op->RunPeriodStampReportChr,
    6123          85 :                                      state.dataGlobal->DayOfSimChr,
    6124             :                                      true);
    6125          85 :             TimePrint = false;
    6126             :         }
    6127             : 
    6128        1645 :         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    6129          14 :             if (!state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.rVariablesScanned()) {
    6130          21 :                 state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
    6131          14 :                     ReportingFrequency::Simulation, op->RVariableTypes, op->NumOfRVariable);
    6132             :             }
    6133          14 :             if (!state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.iVariablesScanned()) {
    6134          21 :                 state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
    6135          14 :                     ReportingFrequency::Simulation, op->IVariableTypes, op->NumOfIVariable);
    6136             :             }
    6137          56 :             state.dataResultsFramework->resultsFramework->RIRunPeriodTSData.newRow(
    6138          42 :                 state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    6139             :         }
    6140        4935 :         for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
    6141      806498 :             for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    6142      803208 :                 if (op->RVariableTypes(Loop).timeStepType == thisTimeStepType) {
    6143      401604 :                     WriteRealVariableOutput(state, op->RVariableTypes(Loop).VarPtr, ReportingFrequency::Simulation);
    6144             :                 }
    6145             :             } // Number of R Variables
    6146             : 
    6147       20422 :             for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    6148       17132 :                 if (op->IVariableTypes(Loop).timeStepType == thisTimeStepType) {
    6149        8566 :                     WriteIntegerVariableOutput(state, op->IVariableTypes(Loop).VarPtr, ReportingFrequency::Simulation);
    6150             :                 }
    6151             :             } // Number of I Variables
    6152             :         }     // thisTimeStepType (Zone, HVAC)
    6153             : 
    6154        1645 :         ReportSMMeters(state, TimePrint);
    6155             : 
    6156        1645 :         op->NumHoursInSim = 0;
    6157             :     }
    6158             : 
    6159             :     // Yearly Block
    6160        2407 :     if (state.dataEnvrn->EndYearFlag) {
    6161           2 :         if (op->TrackingYearlyVariables) {
    6162           0 :             WriteYearlyTimeStamp(state, state.files.eso, op->YearlyStampReportChr, state.dataGlobal->CalendarYearChr, true);
    6163           0 :             TimePrint = false;
    6164             :         }
    6165           2 :         if (state.dataResultsFramework->resultsFramework->timeSeriesEnabled()) {
    6166           0 :             if (!state.dataResultsFramework->resultsFramework->RIYearlyTSData.rVariablesScanned()) {
    6167           0 :                 state.dataResultsFramework->resultsFramework->initializeRTSDataFrame(
    6168           0 :                     ReportingFrequency::Yearly, op->RVariableTypes, op->NumOfRVariable);
    6169             :             }
    6170           0 :             if (!state.dataResultsFramework->resultsFramework->RIYearlyTSData.iVariablesScanned()) {
    6171           0 :                 state.dataResultsFramework->resultsFramework->initializeITSDataFrame(
    6172           0 :                     ReportingFrequency::Yearly, op->IVariableTypes, op->NumOfIVariable);
    6173             :             }
    6174           0 :             state.dataResultsFramework->resultsFramework->RIYearlyTSData.newRow(
    6175           0 :                 state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->HourOfDay, 0);
    6176             :         }
    6177           6 :         for (auto &thisTimeStepType : {TimeStepType::Zone, TimeStepType::System}) { // Zone, HVAC
    6178         516 :             for (int Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    6179         512 :                 if (op->RVariableTypes(Loop).timeStepType == thisTimeStepType) {
    6180         256 :                     WriteRealVariableOutput(state, op->RVariableTypes(Loop).VarPtr, ReportingFrequency::Yearly);
    6181             :                 }
    6182             :             } // Number of R Variables
    6183             : 
    6184           8 :             for (int Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    6185           4 :                 if (op->IVariableTypes(Loop).timeStepType == thisTimeStepType) {
    6186           2 :                     WriteIntegerVariableOutput(state, op->IVariableTypes(Loop).VarPtr, ReportingFrequency::Yearly);
    6187             :                 }
    6188             :             } // Number of I Variables
    6189             :         }     // thisTimeStepType (Zone, HVAC)
    6190             : 
    6191           2 :         ReportYRMeters(state, TimePrint);
    6192             : 
    6193           2 :         state.dataGlobal->CalendarYear += 1;
    6194           2 :         state.dataGlobal->CalendarYearChr = fmt::to_string(state.dataGlobal->CalendarYear);
    6195             :     }
    6196             : }
    6197             : 
    6198     1296238 : void AssignReportNumber(EnergyPlusData &state, int &ReportNumber)
    6199             : {
    6200             : 
    6201             :     // SUBROUTINE INFORMATION:
    6202             :     //       AUTHOR         Linda K. Lawrie
    6203             :     //       DATE WRITTEN   December 1997
    6204             :     //       MODIFIED       na
    6205             :     //       RE-ENGINEERED  na
    6206             : 
    6207             :     // PURPOSE OF THIS SUBROUTINE:
    6208             :     // This subroutine returns the next report number available.  The report number
    6209             :     // is used in output reports as a key.
    6210             : 
    6211             :     // METHODOLOGY EMPLOYED:
    6212             :     // Use internal ReportNumberCounter to maintain current report numbers.
    6213             : 
    6214             :     // REFERENCES:
    6215             :     // na
    6216             : 
    6217             :     // USE STATEMENTS:
    6218             :     using namespace OutputProcessor;
    6219             : 
    6220             :     // Locals
    6221             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    6222             : 
    6223             :     // FUNCTION PARAMETER DEFINITIONS:
    6224             :     // na
    6225             : 
    6226             :     // INTERFACE BLOCK SPECIFICATIONS:
    6227             :     // na
    6228             : 
    6229             :     // DERIVED TYPE DEFINITIONS:
    6230             :     // na
    6231             : 
    6232             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6233             : 
    6234     1296238 :     ++state.dataOutputProcessor->ReportNumberCounter;
    6235     1296238 :     ReportNumber = state.dataOutputProcessor->ReportNumberCounter;
    6236     1296238 : }
    6237             : 
    6238         769 : void GenOutputVariablesAuditReport(EnergyPlusData &state)
    6239             : {
    6240             : 
    6241             :     // SUBROUTINE INFORMATION:
    6242             :     //       AUTHOR         Linda Lawrie
    6243             :     //       DATE WRITTEN   February 2000
    6244             :     //       MODIFIED       na
    6245             :     //       RE-ENGINEERED  na
    6246             : 
    6247             :     // PURPOSE OF THIS SUBROUTINE:
    6248             :     // This subroutine reports (to the .err file) any report variables
    6249             :     // which were requested but not "setup" during the run.  These will
    6250             :     // either be items that were not used in the IDF file or misspellings
    6251             :     // of report variable names.
    6252             : 
    6253             :     // METHODOLOGY EMPLOYED:
    6254             :     // Use flagged data structure in OutputProcessor.
    6255             : 
    6256             :     // Using/Aliasing
    6257             :     using namespace OutputProcessor;
    6258             : 
    6259             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6260             :     int Loop;
    6261         769 :     auto &op(state.dataOutputProcessor);
    6262             :     std::map<ReportingFrequency, std::string> reportFrequency({{ReportingFrequency::EachCall, "Detailed"},
    6263             :                                                                {ReportingFrequency::TimeStep, "TimeStep"},
    6264             :                                                                {ReportingFrequency::Hourly, "Hourly"},
    6265             :                                                                {ReportingFrequency::Daily, "Daily"},
    6266             :                                                                {ReportingFrequency::Monthly, "Monthly"},
    6267        1538 :                                                                {ReportingFrequency::Yearly, "Annual"}});
    6268             : 
    6269       21119 :     for (Loop = 1; Loop <= op->NumOfReqVariables; ++Loop) {
    6270       20350 :         if (op->ReqRepVars(Loop).Used) continue;
    6271          77 :         if (op->ReqRepVars(Loop).Key.empty()) op->ReqRepVars(Loop).Key = "*";
    6272          77 :         if (has(op->ReqRepVars(Loop).VarName, "OPAQUE SURFACE INSIDE FACE CONDUCTION") && !state.dataGlobal->DisplayAdvancedReportVariables &&
    6273           0 :             !state.dataOutputProcessor->OpaqSurfWarned) {
    6274           0 :             ShowWarningError(state, R"(Variables containing "Opaque Surface Inside Face Conduction" are now "advanced" variables.)");
    6275           0 :             ShowContinueError(state, "You must enter the \"Output:Diagnostics,DisplayAdvancedReportVariables;\" statement to view.");
    6276           0 :             ShowContinueError(state, "First, though, read cautionary statements in the \"InputOutputReference\" document.");
    6277           0 :             state.dataOutputProcessor->OpaqSurfWarned = true;
    6278             :         }
    6279          77 :         if (!state.dataOutputProcessor->Rept) {
    6280          19 :             ShowWarningError(state, "The following Report Variables were requested but not generated -- check.rdd file");
    6281          19 :             ShowContinueError(state, "Either the IDF did not contain these elements, the variable name is misspelled,");
    6282          19 :             ShowContinueError(state,
    6283             :                               "or the requested variable is an advanced output which requires Output : Diagnostics, DisplayAdvancedReportVariables;");
    6284          19 :             state.dataOutputProcessor->Rept = true;
    6285             :         }
    6286         231 :         ShowMessage(state,
    6287         154 :                     "Key=" + op->ReqRepVars(Loop).Key + ", VarName=" + op->ReqRepVars(Loop).VarName +
    6288         231 :                         ", Frequency=" + reportFrequency[op->ReqRepVars(Loop).frequency]);
    6289             :     }
    6290         769 : }
    6291             : 
    6292         769 : void UpdateMeterReporting(EnergyPlusData &state)
    6293             : {
    6294             : 
    6295             :     // SUBROUTINE INFORMATION:
    6296             :     //       AUTHOR         Linda Lawrie
    6297             :     //       DATE WRITTEN   January 2001
    6298             :     //       MODIFIED       February 2007 -- add cumulative meter reporting
    6299             :     //                      January 2012 -- add predefined tabular meter reporting
    6300             :     //       RE-ENGINEERED  na
    6301             : 
    6302             :     // PURPOSE OF THIS SUBROUTINE:
    6303             :     // This subroutine is called at the end of the first HVAC iteration and
    6304             :     // sets up the reporting for the Energy Meters.  It also may show a fatal error
    6305             :     // if errors occurred during initial SetupOutputVariable processing.  It "gets"
    6306             :     // the Report Meter input:
    6307             :     // Report Meter,
    6308             :     //        \memo Meters requested here show up on eplusout.eso and eplusout.mtr
    6309             :     //   A1 , \field Meter_Name
    6310             :     //        \required-field
    6311             :     //        \note Form is EnergyUseType:..., e.g. Electricity:* for all Electricity meters
    6312             :     //        \note or EndUse:..., e.g. InteriorLights:* for all interior lights
    6313             :     //        \note Report MeterFileOnly puts results on the eplusout.mtr file only
    6314             :     //   A2 ; \field Reporting_Frequency
    6315             :     //        \type choice
    6316             :     //        \key timestep
    6317             :     //        \note timestep refers to the zone timestep/timestep in hour value
    6318             :     //        \note runperiod, environment, and annual are the same
    6319             :     //        \key hourly
    6320             :     //        \key daily
    6321             :     //        \key monthly
    6322             :     //        \key runperiod
    6323             :     //        \key environment
    6324             :     //        \key annual
    6325             :     //        \note runperiod, environment, and annual are synonymous
    6326             :     // Report MeterFileOnly,
    6327             :     //        \memo same reporting as Report Meter -- goes to eplusout.mtr only
    6328             :     //   A1 , \field Meter_Name
    6329             :     //        \required-field
    6330             :     //        \note Form is EnergyUseType:..., e.g. Electricity:* for all Electricity meters
    6331             :     //        \note or EndUse:..., e.g. InteriorLights:* for all interior lights
    6332             :     //        \note Report MeterFileOnly puts results on the eplusout.mtr file only
    6333             :     //   A2 ; \field Reporting_Frequency
    6334             :     //        \type choice
    6335             :     //        \key timestep
    6336             :     //        \note timestep refers to the zone timestep/timestep in hour value
    6337             :     //        \note runperiod, environment, and annual are the same
    6338             :     //        \key hourly
    6339             :     //        \key daily
    6340             :     //        \key monthly
    6341             :     //        \key runperiod
    6342             :     //        \key environment
    6343             :     //        \key annual
    6344             :     //        \note runperiod, environment, and annual are synonymous
    6345             : 
    6346             :     // Using/Aliasing
    6347             :     using namespace OutputProcessor;
    6348             : 
    6349             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6350             :     int Loop;
    6351        1538 :     Array1D_string Alphas(2);
    6352        1538 :     Array1D<Real64> Numbers(1);
    6353             :     int NumAlpha;
    6354             :     int NumNumbers;
    6355             :     int IOStat;
    6356             :     int NumReqMeters;
    6357             :     int NumReqMeterFOs;
    6358             : 
    6359         769 :     bool ErrorsFound(false); // If errors detected in input
    6360         769 :     auto &op(state.dataOutputProcessor);
    6361             : 
    6362         769 :     GetCustomMeterInput(state, ErrorsFound);
    6363         769 :     if (ErrorsFound) {
    6364           0 :         op->ErrorsLogged = true;
    6365             :     }
    6366             : 
    6367             :     // Helper lambda to locate a meter index from its name. Returns a negative value if not found
    6368             :     auto setupMeterFromMeterName =
    6369       26576 :         [&state](std::string &name, std::string const &freqString, bool MeterFileOnlyIndicator, bool CumulativeIndicator) -> bool {
    6370        6635 :         bool result = false;
    6371             : 
    6372        6635 :         auto varnameLen = index(name, '[');
    6373        6635 :         if (varnameLen != std::string::npos) {
    6374           0 :             name.erase(varnameLen);
    6375             :         }
    6376             : 
    6377        6635 :         auto &op(state.dataOutputProcessor);
    6378             : 
    6379        6635 :         std::string::size_type wildCardPosition = index(name, '*');
    6380             : 
    6381        6635 :         if (wildCardPosition == std::string::npos) {
    6382        6611 :             int meterIndex = UtilityRoutines::FindItem(name, op->EnergyMeters);
    6383        6611 :             if (meterIndex > 0) {
    6384        6549 :                 ReportingFrequency ReportFreq = determineFrequency(state, freqString);
    6385       13098 :                 SetInitialMeterReportingAndOutputNames(state, meterIndex, MeterFileOnlyIndicator, ReportFreq, CumulativeIndicator);
    6386        6549 :                 result = true;
    6387             :             }
    6388             :         } else { // Wildcard input
    6389          24 :             ReportingFrequency ReportFreq = determineFrequency(state, freqString);
    6390        2399 :             for (int meterIndex = 1; meterIndex <= op->NumEnergyMeters; ++meterIndex) {
    6391        2375 :                 if (UtilityRoutines::SameString(op->EnergyMeters(meterIndex).Name.substr(0, wildCardPosition), name.substr(0, wildCardPosition))) {
    6392         368 :                     SetInitialMeterReportingAndOutputNames(state, meterIndex, MeterFileOnlyIndicator, ReportFreq, CumulativeIndicator);
    6393         184 :                     result = true;
    6394             :                 }
    6395             :             }
    6396             :         }
    6397             : 
    6398        6635 :         return result;
    6399         769 :     };
    6400             : 
    6401         769 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
    6402         769 :     cCurrentModuleObject = "Output:Meter";
    6403         769 :     NumReqMeters = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    6404             : 
    6405        1586 :     for (Loop = 1; Loop <= NumReqMeters; ++Loop) {
    6406             : 
    6407        4085 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    6408             :                                                                  cCurrentModuleObject,
    6409             :                                                                  Loop,
    6410             :                                                                  Alphas,
    6411             :                                                                  NumAlpha,
    6412             :                                                                  Numbers,
    6413             :                                                                  NumNumbers,
    6414             :                                                                  IOStat,
    6415         817 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
    6416         817 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
    6417         817 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
    6418         817 :                                                                  state.dataIPShortCut->cNumericFieldNames);
    6419             : 
    6420         817 :         bool meterFileOnlyIndicator = false;
    6421         817 :         bool cumulativeIndicator = false;
    6422         817 :         if (!setupMeterFromMeterName(Alphas(1), Alphas(2), meterFileOnlyIndicator, cumulativeIndicator)) {
    6423          48 :             ShowWarningError(state,
    6424          32 :                              cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + "=\"" + Alphas(1) + "\" - not found.");
    6425             :         }
    6426             :     }
    6427             : 
    6428         769 :     cCurrentModuleObject = "Output:Meter:MeterFileOnly";
    6429         769 :     NumReqMeterFOs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    6430        6582 :     for (Loop = 1; Loop <= NumReqMeterFOs; ++Loop) {
    6431             : 
    6432       29065 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    6433             :                                                                  cCurrentModuleObject,
    6434             :                                                                  Loop,
    6435             :                                                                  Alphas,
    6436             :                                                                  NumAlpha,
    6437             :                                                                  Numbers,
    6438             :                                                                  NumNumbers,
    6439             :                                                                  IOStat,
    6440        5813 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
    6441        5813 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
    6442        5813 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
    6443        5813 :                                                                  state.dataIPShortCut->cNumericFieldNames);
    6444             : 
    6445        5813 :         bool meterFileOnlyIndicator = true;
    6446        5813 :         bool cumulativeIndicator = false;
    6447        5813 :         if (!setupMeterFromMeterName(Alphas(1), Alphas(2), meterFileOnlyIndicator, cumulativeIndicator)) {
    6448         138 :             ShowWarningError(state,
    6449          92 :                              cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + "=\"" + Alphas(1) + "\" - not found.");
    6450             :         }
    6451             :     }
    6452             : 
    6453         769 :     cCurrentModuleObject = "Output:Meter:Cumulative";
    6454         769 :     NumReqMeters = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    6455             : 
    6456         770 :     for (Loop = 1; Loop <= NumReqMeters; ++Loop) {
    6457             : 
    6458           5 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    6459             :                                                                  cCurrentModuleObject,
    6460             :                                                                  Loop,
    6461             :                                                                  Alphas,
    6462             :                                                                  NumAlpha,
    6463             :                                                                  Numbers,
    6464             :                                                                  NumNumbers,
    6465             :                                                                  IOStat,
    6466           1 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
    6467           1 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
    6468           1 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
    6469           1 :                                                                  state.dataIPShortCut->cNumericFieldNames);
    6470             : 
    6471           1 :         bool meterFileOnlyIndicator = false;
    6472           1 :         bool cumulativeIndicator = true;
    6473           1 :         if (!setupMeterFromMeterName(Alphas(1), Alphas(2), meterFileOnlyIndicator, cumulativeIndicator)) {
    6474           0 :             ShowWarningError(state,
    6475           0 :                              cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + "=\"" + Alphas(1) + "\" - not found.");
    6476             :         }
    6477             :     }
    6478             : 
    6479         769 :     cCurrentModuleObject = "Output:Meter:Cumulative:MeterFileOnly";
    6480         769 :     NumReqMeterFOs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    6481         773 :     for (Loop = 1; Loop <= NumReqMeterFOs; ++Loop) {
    6482             : 
    6483          20 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    6484             :                                                                  cCurrentModuleObject,
    6485             :                                                                  Loop,
    6486             :                                                                  Alphas,
    6487             :                                                                  NumAlpha,
    6488             :                                                                  Numbers,
    6489             :                                                                  NumNumbers,
    6490             :                                                                  IOStat,
    6491           4 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
    6492           4 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
    6493           4 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
    6494           4 :                                                                  state.dataIPShortCut->cNumericFieldNames);
    6495             : 
    6496           4 :         bool meterFileOnlyIndicator = true;
    6497           4 :         bool cumulativeIndicator = true;
    6498           4 :         if (!setupMeterFromMeterName(Alphas(1), Alphas(2), meterFileOnlyIndicator, cumulativeIndicator)) {
    6499           0 :             ShowWarningError(state,
    6500           0 :                              cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + "=\"" + Alphas(1) + "\" - not found.");
    6501             :         }
    6502             :     }
    6503             : 
    6504         769 :     ReportMeterDetails(state);
    6505             : 
    6506         769 :     if (op->ErrorsLogged) {
    6507           0 :         ShowFatalError(state, "UpdateMeterReporting: Previous Meter Specification errors cause program termination.");
    6508             :     }
    6509             : 
    6510         769 :     op->MeterValue.dimension(op->NumEnergyMeters, 0.0);
    6511         769 : }
    6512             : 
    6513        6733 : void SetInitialMeterReportingAndOutputNames(EnergyPlusData &state,
    6514             :                                             int const WhichMeter,              // Which meter number
    6515             :                                             bool const MeterFileOnlyIndicator, // true if this is a meter file only reporting
    6516             :                                             OutputProcessor::ReportingFrequency const FrequencyIndicator, // at what frequency is the meter reported
    6517             :                                             bool const CumulativeIndicator // true if this is a Cumulative meter reporting
    6518             : )
    6519             : {
    6520             : 
    6521             :     // SUBROUTINE INFORMATION:
    6522             :     //       AUTHOR         Linda Lawrie
    6523             :     //       DATE WRITTEN   February 2007
    6524             :     //       MODIFIED       na
    6525             :     //       RE-ENGINEERED  na
    6526             : 
    6527             :     // PURPOSE OF THIS SUBROUTINE:
    6528             :     // Set values and output initial names to output files.
    6529             : 
    6530             :     // Using/Aliasing
    6531             :     using namespace OutputProcessor;
    6532             : 
    6533             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6534             :     int indexGroupKey;
    6535       13466 :     std::string indexGroup;
    6536        6733 :     auto &op(state.dataOutputProcessor);
    6537             : 
    6538        6733 :     if ((FrequencyIndicator == ReportingFrequency::EachCall) ||
    6539             :         (FrequencyIndicator == ReportingFrequency::TimeStep)) { // roll "detailed" into TimeStep
    6540         100 :         if (!CumulativeIndicator) {
    6541          50 :             if (MeterFileOnlyIndicator) {
    6542           8 :                 if (op->EnergyMeters(WhichMeter).RptTS) {
    6543           0 :                     ShowWarningError(state,
    6544           0 :                                      "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
    6545           0 :                                          R"(" (TimeStep), already on "Output:Meter". Will report to both )" +
    6546           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6547             :                 }
    6548             :             }
    6549          50 :             if (!op->EnergyMeters(WhichMeter).RptTS) {
    6550          50 :                 op->EnergyMeters(WhichMeter).RptTS = true;
    6551          50 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptTSFO = true;
    6552          50 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6553          50 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6554         250 :                 WriteMeterDictionaryItem(state,
    6555             :                                          FrequencyIndicator,
    6556             :                                          StoreType::Summed,
    6557          50 :                                          op->EnergyMeters(WhichMeter).TSRptNum,
    6558             :                                          indexGroupKey,
    6559             :                                          indexGroup,
    6560          50 :                                          op->EnergyMeters(WhichMeter).TSRptNumChr,
    6561          50 :                                          op->EnergyMeters(WhichMeter).Name,
    6562          50 :                                          op->EnergyMeters(WhichMeter).Units,
    6563             :                                          false,
    6564             :                                          MeterFileOnlyIndicator);
    6565             :             }
    6566             :         } else {
    6567           0 :             if (MeterFileOnlyIndicator) {
    6568           0 :                 if (op->EnergyMeters(WhichMeter).RptAccTS) {
    6569           0 :                     ShowWarningError(state,
    6570           0 :                                      "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
    6571           0 :                                          R"(" (TimeStep), already on "Output:Meter". Will report to both )" +
    6572           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6573             :                 }
    6574             :             }
    6575           0 :             if (!op->EnergyMeters(WhichMeter).RptAccTS) {
    6576           0 :                 op->EnergyMeters(WhichMeter).RptAccTS = true;
    6577           0 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccTSFO = true;
    6578           0 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6579           0 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6580           0 :                 WriteMeterDictionaryItem(state,
    6581             :                                          FrequencyIndicator,
    6582             :                                          StoreType::Summed,
    6583           0 :                                          op->EnergyMeters(WhichMeter).TSAccRptNum,
    6584             :                                          indexGroupKey,
    6585             :                                          indexGroup,
    6586           0 :                                          fmt::to_string(op->EnergyMeters(WhichMeter).TSAccRptNum),
    6587           0 :                                          op->EnergyMeters(WhichMeter).Name,
    6588           0 :                                          op->EnergyMeters(WhichMeter).Units,
    6589             :                                          true,
    6590             :                                          MeterFileOnlyIndicator);
    6591             :             }
    6592             :         }
    6593        6683 :     } else if (FrequencyIndicator == ReportingFrequency::Hourly) {
    6594         702 :         if (!CumulativeIndicator) {
    6595         702 :             if (MeterFileOnlyIndicator) {
    6596         151 :                 if (op->EnergyMeters(WhichMeter).RptHR) {
    6597           9 :                     ShowWarningError(state,
    6598           6 :                                      "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
    6599           6 :                                          R"(" (Hourly), already on "Output:Meter". Will report to both )" +
    6600          12 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6601             :                 }
    6602             :             }
    6603         702 :             if (!op->EnergyMeters(WhichMeter).RptHR) {
    6604         699 :                 op->EnergyMeters(WhichMeter).RptHR = true;
    6605         699 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptHRFO = true;
    6606         699 :                 if (!MeterFileOnlyIndicator) op->TrackingHourlyVariables = true;
    6607         699 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6608         699 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6609        3495 :                 WriteMeterDictionaryItem(state,
    6610             :                                          FrequencyIndicator,
    6611             :                                          StoreType::Summed,
    6612         699 :                                          op->EnergyMeters(WhichMeter).HRRptNum,
    6613             :                                          indexGroupKey,
    6614             :                                          indexGroup,
    6615         699 :                                          op->EnergyMeters(WhichMeter).HRRptNumChr,
    6616         699 :                                          op->EnergyMeters(WhichMeter).Name,
    6617         699 :                                          op->EnergyMeters(WhichMeter).Units,
    6618             :                                          false,
    6619             :                                          MeterFileOnlyIndicator);
    6620             :             }
    6621             :         } else {
    6622           0 :             if (MeterFileOnlyIndicator) {
    6623           0 :                 if (op->EnergyMeters(WhichMeter).RptAccHR) {
    6624           0 :                     ShowWarningError(state,
    6625           0 :                                      "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
    6626           0 :                                          R"(" (Hourly), already on "Output:Meter". Will report to both )" +
    6627           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6628             :                 }
    6629             :             }
    6630           0 :             if (!op->EnergyMeters(WhichMeter).RptAccHR) {
    6631           0 :                 op->EnergyMeters(WhichMeter).RptAccHR = true;
    6632           0 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccHRFO = true;
    6633           0 :                 if (!MeterFileOnlyIndicator) op->TrackingHourlyVariables = true;
    6634           0 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6635           0 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6636           0 :                 WriteMeterDictionaryItem(state,
    6637             :                                          FrequencyIndicator,
    6638             :                                          StoreType::Summed,
    6639           0 :                                          op->EnergyMeters(WhichMeter).HRAccRptNum,
    6640             :                                          indexGroupKey,
    6641             :                                          indexGroup,
    6642           0 :                                          fmt::to_string(op->EnergyMeters(WhichMeter).HRAccRptNum),
    6643           0 :                                          op->EnergyMeters(WhichMeter).Name,
    6644           0 :                                          op->EnergyMeters(WhichMeter).Units,
    6645             :                                          true,
    6646             :                                          MeterFileOnlyIndicator);
    6647             :             }
    6648             :         }
    6649        5981 :     } else if (FrequencyIndicator == ReportingFrequency::Daily) {
    6650          71 :         if (!CumulativeIndicator) {
    6651          71 :             if (MeterFileOnlyIndicator) {
    6652           1 :                 if (op->EnergyMeters(WhichMeter).RptDY) {
    6653           0 :                     ShowWarningError(state,
    6654           0 :                                      "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
    6655           0 :                                          R"(" (Daily), already on "Output:Meter". Will report to both )" +
    6656           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6657             :                 }
    6658             :             }
    6659          71 :             if (!op->EnergyMeters(WhichMeter).RptDY) {
    6660          71 :                 op->EnergyMeters(WhichMeter).RptDY = true;
    6661          71 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptDYFO = true;
    6662          71 :                 if (!MeterFileOnlyIndicator) op->TrackingDailyVariables = true;
    6663          71 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6664          71 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6665         355 :                 WriteMeterDictionaryItem(state,
    6666             :                                          FrequencyIndicator,
    6667             :                                          StoreType::Summed,
    6668          71 :                                          op->EnergyMeters(WhichMeter).DYRptNum,
    6669             :                                          indexGroupKey,
    6670             :                                          indexGroup,
    6671          71 :                                          op->EnergyMeters(WhichMeter).DYRptNumChr,
    6672          71 :                                          op->EnergyMeters(WhichMeter).Name,
    6673          71 :                                          op->EnergyMeters(WhichMeter).Units,
    6674             :                                          false,
    6675             :                                          MeterFileOnlyIndicator);
    6676             :             }
    6677             :         } else {
    6678           0 :             if (MeterFileOnlyIndicator) {
    6679           0 :                 if (op->EnergyMeters(WhichMeter).RptAccDY) {
    6680           0 :                     ShowWarningError(state,
    6681           0 :                                      "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
    6682           0 :                                          R"(" (Hourly), already on "Output:Meter". Will report to both )" +
    6683           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6684             :                 }
    6685             :             }
    6686           0 :             if (!op->EnergyMeters(WhichMeter).RptAccDY) {
    6687           0 :                 op->EnergyMeters(WhichMeter).RptAccDY = true;
    6688           0 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccDYFO = true;
    6689           0 :                 if (!MeterFileOnlyIndicator) op->TrackingDailyVariables = true;
    6690           0 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6691           0 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6692           0 :                 WriteMeterDictionaryItem(state,
    6693             :                                          FrequencyIndicator,
    6694             :                                          StoreType::Summed,
    6695           0 :                                          op->EnergyMeters(WhichMeter).DYAccRptNum,
    6696             :                                          indexGroupKey,
    6697             :                                          indexGroup,
    6698           0 :                                          fmt::to_string(op->EnergyMeters(WhichMeter).DYAccRptNum),
    6699           0 :                                          op->EnergyMeters(WhichMeter).Name,
    6700           0 :                                          op->EnergyMeters(WhichMeter).Units,
    6701             :                                          true,
    6702             :                                          MeterFileOnlyIndicator);
    6703             :             }
    6704             :         }
    6705        5910 :     } else if (FrequencyIndicator == ReportingFrequency::Monthly) {
    6706        3003 :         if (!CumulativeIndicator) {
    6707        2998 :             if (MeterFileOnlyIndicator) {
    6708        2862 :                 if (op->EnergyMeters(WhichMeter).RptMN) {
    6709           0 :                     ShowWarningError(state,
    6710           0 :                                      "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
    6711           0 :                                          R"(" (Monthly), already on "Output:Meter". Will report to both )" +
    6712           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6713             :                 }
    6714             :             }
    6715        2998 :             if (!op->EnergyMeters(WhichMeter).RptMN) {
    6716        2998 :                 op->EnergyMeters(WhichMeter).RptMN = true;
    6717        2998 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptMNFO = true;
    6718        2998 :                 if (!MeterFileOnlyIndicator) op->TrackingMonthlyVariables = true;
    6719        2998 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6720        2998 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6721       14990 :                 WriteMeterDictionaryItem(state,
    6722             :                                          FrequencyIndicator,
    6723             :                                          StoreType::Summed,
    6724        2998 :                                          op->EnergyMeters(WhichMeter).MNRptNum,
    6725             :                                          indexGroupKey,
    6726             :                                          indexGroup,
    6727        2998 :                                          op->EnergyMeters(WhichMeter).MNRptNumChr,
    6728        2998 :                                          op->EnergyMeters(WhichMeter).Name,
    6729        2998 :                                          op->EnergyMeters(WhichMeter).Units,
    6730             :                                          false,
    6731             :                                          MeterFileOnlyIndicator);
    6732             :             }
    6733             :         } else {
    6734           5 :             if (MeterFileOnlyIndicator) {
    6735           4 :                 if (op->EnergyMeters(WhichMeter).RptAccMN) {
    6736           0 :                     ShowWarningError(state,
    6737           0 :                                      "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
    6738           0 :                                          R"(" (Monthly), already on "Output:Meter". Will report to both )" +
    6739           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6740             :                 }
    6741             :             }
    6742           5 :             if (!op->EnergyMeters(WhichMeter).RptAccMN) {
    6743           5 :                 op->EnergyMeters(WhichMeter).RptAccMN = true;
    6744           5 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccMNFO = true;
    6745           5 :                 if (!MeterFileOnlyIndicator) op->TrackingMonthlyVariables = true;
    6746           5 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6747           5 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6748          20 :                 WriteMeterDictionaryItem(state,
    6749             :                                          FrequencyIndicator,
    6750             :                                          StoreType::Summed,
    6751           5 :                                          op->EnergyMeters(WhichMeter).MNAccRptNum,
    6752             :                                          indexGroupKey,
    6753             :                                          indexGroup,
    6754          10 :                                          fmt::to_string(op->EnergyMeters(WhichMeter).MNAccRptNum),
    6755           5 :                                          op->EnergyMeters(WhichMeter).Name,
    6756           5 :                                          op->EnergyMeters(WhichMeter).Units,
    6757             :                                          true,
    6758             :                                          MeterFileOnlyIndicator);
    6759             :             }
    6760             :         }
    6761        2907 :     } else if (FrequencyIndicator == ReportingFrequency::Yearly) {
    6762          83 :         if (!CumulativeIndicator) {
    6763          83 :             if (MeterFileOnlyIndicator) {
    6764          83 :                 if (op->EnergyMeters(WhichMeter).RptYR) {
    6765           0 :                     ShowWarningError(state,
    6766           0 :                                      "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
    6767           0 :                                          R"(" (Annual), already on "Output:Meter". Will report to both )" +
    6768           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6769             :                 }
    6770             :             }
    6771          83 :             if (!op->EnergyMeters(WhichMeter).RptYR) {
    6772          83 :                 op->EnergyMeters(WhichMeter).RptYR = true;
    6773          83 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptYRFO = true;
    6774          83 :                 if (!MeterFileOnlyIndicator) op->TrackingYearlyVariables = true;
    6775          83 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6776          83 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6777         415 :                 WriteMeterDictionaryItem(state,
    6778             :                                          FrequencyIndicator,
    6779             :                                          StoreType::Summed,
    6780          83 :                                          op->EnergyMeters(WhichMeter).YRRptNum,
    6781             :                                          indexGroupKey,
    6782             :                                          indexGroup,
    6783          83 :                                          op->EnergyMeters(WhichMeter).YRRptNumChr,
    6784          83 :                                          op->EnergyMeters(WhichMeter).Name,
    6785          83 :                                          op->EnergyMeters(WhichMeter).Units,
    6786             :                                          false,
    6787             :                                          MeterFileOnlyIndicator);
    6788             :             }
    6789             :         } else {
    6790           0 :             if (MeterFileOnlyIndicator) {
    6791           0 :                 if (op->EnergyMeters(WhichMeter).RptAccYR) {
    6792           0 :                     ShowWarningError(state,
    6793           0 :                                      "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
    6794           0 :                                          R"(" (Annual), already on "Output:Meter". Will report to both )" +
    6795           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6796             :                 }
    6797             :             }
    6798           0 :             if (!op->EnergyMeters(WhichMeter).RptAccYR) {
    6799           0 :                 op->EnergyMeters(WhichMeter).RptAccYR = true;
    6800           0 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccYRFO = true;
    6801           0 :                 if (!MeterFileOnlyIndicator) op->TrackingYearlyVariables = true;
    6802           0 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6803           0 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6804           0 :                 WriteMeterDictionaryItem(state,
    6805             :                                          FrequencyIndicator,
    6806             :                                          StoreType::Summed,
    6807           0 :                                          op->EnergyMeters(WhichMeter).YRAccRptNum,
    6808             :                                          indexGroupKey,
    6809             :                                          indexGroup,
    6810           0 :                                          fmt::to_string(op->EnergyMeters(WhichMeter).YRAccRptNum),
    6811           0 :                                          op->EnergyMeters(WhichMeter).Name,
    6812           0 :                                          op->EnergyMeters(WhichMeter).Units,
    6813             :                                          true,
    6814             :                                          MeterFileOnlyIndicator);
    6815             :             }
    6816             :         }
    6817        2824 :     } else if (FrequencyIndicator == ReportingFrequency::Simulation) {
    6818        2824 :         if (!CumulativeIndicator) {
    6819        2824 :             if (MeterFileOnlyIndicator) {
    6820        2662 :                 if (op->EnergyMeters(WhichMeter).RptSM) {
    6821           0 :                     ShowWarningError(state,
    6822           0 :                                      "Output:Meter:MeterFileOnly requested for \"" + op->EnergyMeters(WhichMeter).Name +
    6823           0 :                                          R"(" (RunPeriod), already on "Output:Meter". Will report to both )" +
    6824           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6825             :                 }
    6826             :             }
    6827        2824 :             if (!op->EnergyMeters(WhichMeter).RptSM) {
    6828        2824 :                 op->EnergyMeters(WhichMeter).RptSM = true;
    6829        2824 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptSMFO = true;
    6830        2824 :                 if (!MeterFileOnlyIndicator) op->TrackingRunPeriodVariables = true;
    6831        2824 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6832        2824 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6833       14120 :                 WriteMeterDictionaryItem(state,
    6834             :                                          FrequencyIndicator,
    6835             :                                          StoreType::Summed,
    6836        2824 :                                          op->EnergyMeters(WhichMeter).SMRptNum,
    6837             :                                          indexGroupKey,
    6838             :                                          indexGroup,
    6839        2824 :                                          op->EnergyMeters(WhichMeter).SMRptNumChr,
    6840        2824 :                                          op->EnergyMeters(WhichMeter).Name,
    6841        2824 :                                          op->EnergyMeters(WhichMeter).Units,
    6842             :                                          false,
    6843             :                                          MeterFileOnlyIndicator);
    6844             :             }
    6845             :         } else {
    6846           0 :             if (MeterFileOnlyIndicator) {
    6847           0 :                 if (op->EnergyMeters(WhichMeter).RptAccSM) {
    6848           0 :                     ShowWarningError(state,
    6849           0 :                                      "Output:Meter:MeterFileOnly requested for \"Cumulative " + op->EnergyMeters(WhichMeter).Name +
    6850           0 :                                          R"(" (RunPeriod), already on "Output:Meter". Will report to both )" +
    6851           0 :                                          state.files.eso.filePath.filename().string() + " and " + state.files.mtr.filePath.filename().string());
    6852             :                 }
    6853             :             }
    6854           0 :             if (!op->EnergyMeters(WhichMeter).RptAccSM) {
    6855           0 :                 op->EnergyMeters(WhichMeter).RptAccSM = true;
    6856           0 :                 if (MeterFileOnlyIndicator) op->EnergyMeters(WhichMeter).RptAccSMFO = true;
    6857           0 :                 if (!MeterFileOnlyIndicator) op->TrackingRunPeriodVariables = true;
    6858           0 :                 indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(WhichMeter).Name);
    6859           0 :                 indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(WhichMeter));
    6860           0 :                 WriteMeterDictionaryItem(state,
    6861             :                                          FrequencyIndicator,
    6862             :                                          StoreType::Summed,
    6863           0 :                                          op->EnergyMeters(WhichMeter).SMAccRptNum,
    6864             :                                          indexGroupKey,
    6865             :                                          indexGroup,
    6866           0 :                                          fmt::to_string(op->EnergyMeters(WhichMeter).SMAccRptNum),
    6867           0 :                                          op->EnergyMeters(WhichMeter).Name,
    6868           0 :                                          op->EnergyMeters(WhichMeter).Units,
    6869             :                                          true,
    6870             :                                          MeterFileOnlyIndicator);
    6871             :             }
    6872             :         }
    6873             :     } else {
    6874             :     }
    6875        6733 : }
    6876             : 
    6877      412682 : int GetMeterIndex(EnergyPlusData &state, std::string const &MeterName)
    6878             : {
    6879             : 
    6880             :     // FUNCTION INFORMATION:
    6881             :     //       AUTHOR         Linda K. Lawrie
    6882             :     //       DATE WRITTEN   August 2002
    6883             :     //       MODIFIED       na
    6884             :     //       RE-ENGINEERED  na
    6885             : 
    6886             :     // PURPOSE OF THIS FUNCTION:
    6887             :     // This function returns a index to the meter "number" (aka assigned report number)
    6888             :     // for the meter name.  If none active for this run, a zero is returned.  This is used later to
    6889             :     // obtain a meter "value".
    6890             : 
    6891             :     // Using/Aliasing
    6892             :     using namespace OutputProcessor;
    6893             :     using SortAndStringUtilities::SetupAndSort;
    6894             : 
    6895             :     // Return value
    6896             :     int MeterIndex;
    6897             : 
    6898             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6899             :     // Valid Meter names because matching case insensitive
    6900             :     //////////// hoisted into namespace changed to GetMeterIndexFirstCall////////////
    6901             :     // static bool FirstCall( true );
    6902             :     ////////////////////////////////////////////////
    6903             :     int Found;
    6904      412682 :     auto &op(state.dataOutputProcessor);
    6905             : 
    6906      412682 :     if (op->GetMeterIndexFirstCall || (state.dataOutputProcessor->NumValidMeters != op->NumEnergyMeters)) {
    6907        2471 :         state.dataOutputProcessor->NumValidMeters = op->NumEnergyMeters;
    6908        2471 :         state.dataOutputProcessor->ValidMeterNames.allocate(state.dataOutputProcessor->NumValidMeters);
    6909      292854 :         for (Found = 1; Found <= state.dataOutputProcessor->NumValidMeters; ++Found) {
    6910      290383 :             state.dataOutputProcessor->ValidMeterNames(Found) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(Found).Name);
    6911             :         }
    6912        2471 :         state.dataOutputProcessor->iValidMeterNames.allocate(state.dataOutputProcessor->NumValidMeters);
    6913        2471 :         SetupAndSort(state.dataOutputProcessor->ValidMeterNames, state.dataOutputProcessor->iValidMeterNames);
    6914        2471 :         op->GetMeterIndexFirstCall = false;
    6915             :     }
    6916             : 
    6917      412682 :     MeterIndex =
    6918      825364 :         UtilityRoutines::FindItemInSortedList(MeterName, state.dataOutputProcessor->ValidMeterNames, state.dataOutputProcessor->NumValidMeters);
    6919      412682 :     if (MeterIndex != 0) MeterIndex = state.dataOutputProcessor->iValidMeterNames(MeterIndex);
    6920             : 
    6921      412682 :     return MeterIndex;
    6922             : }
    6923             : 
    6924          23 : std::string GetMeterResourceType(EnergyPlusData &state, int const MeterNumber) // Which Meter Number (from GetMeterIndex)
    6925             : {
    6926             : 
    6927             :     // FUNCTION INFORMATION:
    6928             :     //       AUTHOR         Linda K. Lawrie
    6929             :     //       DATE WRITTEN   August 2002
    6930             :     //       MODIFIED       na
    6931             :     //       RE-ENGINEERED  na
    6932             : 
    6933             :     // PURPOSE OF THIS FUNCTION:
    6934             :     // This function returns the character string of Resource Type for the
    6935             :     // given meter number/index. If MeterNumber is 0, ResourceType=Invalid/Unknown.
    6936             : 
    6937             :     // METHODOLOGY EMPLOYED:
    6938             :     // na
    6939             : 
    6940             :     // REFERENCES:
    6941             :     // na
    6942             : 
    6943             :     // Using/Aliasing
    6944             :     using namespace OutputProcessor;
    6945             : 
    6946             :     // Return value
    6947          23 :     std::string ResourceType;
    6948             : 
    6949             :     // Locals
    6950             :     // FUNCTION ARGUMENT DEFINITIONS:
    6951             : 
    6952             :     // FUNCTION PARAMETER DEFINITIONS:
    6953             :     // na
    6954             : 
    6955             :     // INTERFACE BLOCK SPECIFICATIONS:
    6956             :     // na
    6957             : 
    6958             :     // DERIVED TYPE DEFINITIONS:
    6959             :     // na
    6960             : 
    6961             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6962          23 :     if (MeterNumber > 0) {
    6963          23 :         ResourceType = state.dataOutputProcessor->EnergyMeters(MeterNumber).ResourceType;
    6964             :     } else {
    6965           0 :         ResourceType = "Invalid/Unknown";
    6966             :     }
    6967             : 
    6968          23 :     return ResourceType;
    6969             : }
    6970             : 
    6971     5032315 : Real64 GetCurrentMeterValue(EnergyPlusData &state, int const MeterNumber) // Which Meter Number (from GetMeterIndex)
    6972             : {
    6973             : 
    6974             :     // FUNCTION INFORMATION:
    6975             :     //       AUTHOR         Linda K. Lawrie
    6976             :     //       DATE WRITTEN   August 2002
    6977             :     //       MODIFIED       na
    6978             :     //       RE-ENGINEERED  na
    6979             : 
    6980             :     // PURPOSE OF THIS FUNCTION:
    6981             :     // This function returns the current meter value (timestep) for the meter number indicated.
    6982             : 
    6983             :     // METHODOLOGY EMPLOYED:
    6984             :     // Uses internal EnergyMeters structure to get value.
    6985             : 
    6986             :     // REFERENCES:
    6987             :     // na
    6988             : 
    6989             :     // Using/Aliasing
    6990             :     using namespace OutputProcessor;
    6991             : 
    6992             :     // Return value
    6993             :     Real64 CurrentMeterValue;
    6994             : 
    6995             :     // Locals
    6996             :     // FUNCTION ARGUMENT DEFINITIONS:
    6997             : 
    6998             :     // FUNCTION PARAMETER DEFINITIONS:
    6999             :     // na
    7000             : 
    7001             :     // INTERFACE BLOCK SPECIFICATIONS:
    7002             :     // na
    7003             : 
    7004             :     // DERIVED TYPE DEFINITIONS:
    7005             :     // na
    7006             : 
    7007             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    7008             :     // na
    7009             : 
    7010     5032315 :     if (MeterNumber > 0) {
    7011     3769147 :         CurrentMeterValue = state.dataOutputProcessor->EnergyMeters(MeterNumber).CurTSValue;
    7012             :     } else {
    7013     1263168 :         CurrentMeterValue = 0.0;
    7014             :     }
    7015             : 
    7016     5032315 :     return CurrentMeterValue;
    7017             : }
    7018             : 
    7019   253370806 : Real64 GetInstantMeterValue(EnergyPlusData &state,
    7020             :                             int const MeterNumber,                             // Which Meter Number (from GetMeterIndex)
    7021             :                             OutputProcessor::TimeStepType const t_timeStepType // Whether this is zone of HVAC
    7022             : )
    7023             : {
    7024             : 
    7025             :     // FUNCTION INFORMATION:
    7026             :     //       AUTHOR         Richard Liesen
    7027             :     //       DATE WRITTEN   February 2003
    7028             :     //       MODIFIED       na
    7029             :     //       RE-ENGINEERED  na
    7030             : 
    7031             :     // PURPOSE OF THIS FUNCTION:
    7032             :     // This function returns the Instantaneous meter value (timestep) for the meter number indicated
    7033             :     //  using TimeStepType to differentiate between Zone and HVAC values.
    7034             : 
    7035             :     // METHODOLOGY EMPLOYED:
    7036             :     // Uses internal EnergyMeters structure to get value.
    7037             : 
    7038             :     // REFERENCES:
    7039             :     // na
    7040             : 
    7041             :     // Using/Aliasing
    7042             :     using namespace OutputProcessor;
    7043             : 
    7044             :     // Return value
    7045   253370806 :     Real64 InstantMeterValue(0.0);
    7046             : 
    7047             :     // Locals
    7048             :     // FUNCTION ARGUMENT DEFINITIONS:
    7049             : 
    7050             :     // FUNCTION PARAMETER DEFINITIONS:
    7051             :     // na
    7052             : 
    7053             :     // INTERFACE BLOCK SPECIFICATIONS:
    7054             :     // na
    7055             : 
    7056             :     // DERIVED TYPE DEFINITIONS:
    7057             :     // na
    7058             : 
    7059             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    7060             : 
    7061             :     //      EnergyMeters(Meter)%TSValue=EnergyMeters(EnergyMeters(Meter)%SourceMeter)%TSValue-MeterValue(Meter)
    7062             : 
    7063   253370806 :     if (MeterNumber == 0) return InstantMeterValue;
    7064    60242367 :     auto &op(state.dataOutputProcessor);
    7065             : 
    7066    60242367 :     auto &energy_meter(op->EnergyMeters(MeterNumber));
    7067    60242367 :     auto &cache_beg(energy_meter.InstMeterCacheStart);
    7068    60242367 :     auto &cache_end(energy_meter.InstMeterCacheEnd);
    7069    60242367 :     if (energy_meter.TypeOfMeter != MtrType::CustomDec) {
    7070             :         // section added to speed up the execution of this routine
    7071             :         // instead of looping through all the VarMeterArrays to see if a RVariableType is used for a
    7072             :         // specific meter, create a list of all the indexes for RVariableType that are used for that
    7073             :         // meter.
    7074    60105151 :         if (cache_beg == 0) { // not yet added to the cache
    7075      244772 :             for (int Loop = 1; Loop <= op->NumVarMeterArrays; ++Loop) {
    7076      241671 :                 auto const &var_meter_on(op->VarMeterArrays(Loop).OnMeters);
    7077     1309367 :                 for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnMeters; Meter <= Meter_end; ++Meter) {
    7078     1091037 :                     if (var_meter_on(Meter) == MeterNumber) {
    7079       23341 :                         IncrementInstMeterCache(state);
    7080       23341 :                         cache_end = op->InstMeterCacheLastUsed;
    7081       23341 :                         if (cache_beg == 0) cache_beg = op->InstMeterCacheLastUsed;
    7082       23341 :                         op->InstMeterCache(op->InstMeterCacheLastUsed) = op->VarMeterArrays(Loop).RepVariable;
    7083       23341 :                         break;
    7084             :                     }
    7085             :                 }
    7086      241671 :                 auto const &var_meter_on_custom(op->VarMeterArrays(Loop).OnCustomMeters);
    7087      245153 :                 for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnCustomMeters; Meter <= Meter_end; ++Meter) {
    7088        3493 :                     if (var_meter_on_custom(Meter) == MeterNumber) {
    7089          11 :                         IncrementInstMeterCache(state);
    7090          11 :                         cache_end = op->InstMeterCacheLastUsed;
    7091          11 :                         if (cache_beg == 0) cache_beg = op->InstMeterCacheLastUsed;
    7092          11 :                         op->InstMeterCache(op->InstMeterCacheLastUsed) = op->VarMeterArrays(Loop).RepVariable;
    7093          11 :                         break;
    7094             :                     }
    7095             :                 } // End Number of Meters Loop
    7096             :             }
    7097             :         }
    7098  1702291435 :         for (int Loop = cache_beg; Loop <= cache_end; ++Loop) {
    7099  1642186284 :             auto &r_var_loop(op->RVariableTypes(op->InstMeterCache(Loop)));
    7100             :             // Separate the Zone variables from the HVAC variables using TimeStepType
    7101  1642186284 :             if (r_var_loop.timeStepType == t_timeStepType) {
    7102   822750953 :                 auto &rVar(r_var_loop.VarPtr);
    7103             :                 // Add to the total all of the appropriate variables
    7104   822750953 :                 InstantMeterValue += (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
    7105             :             }
    7106             :         }
    7107             :     } else { // MeterType_CustomDec
    7108             :         // Get Source Meter value
    7109             :         // Loop through all report meters to find correct report variables to add to instant meter total
    7110    63570754 :         for (int Loop = 1; Loop <= op->NumVarMeterArrays; ++Loop) {
    7111    63433538 :             auto &r_var_loop(op->RVariableTypes(op->VarMeterArrays(Loop).RepVariable));
    7112             : 
    7113    63433538 :             auto const &var_meter_on(op->VarMeterArrays(Loop).OnMeters);
    7114   376590132 :             for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnMeters; Meter <= Meter_end; ++Meter) {
    7115   315335129 :                 if (var_meter_on(Meter) == energy_meter.SourceMeter) {
    7116             :                     // Separate the Zone variables from the HVAC variables using TimeStepType
    7117     4357070 :                     if (r_var_loop.timeStepType == t_timeStepType) {
    7118     2178535 :                         auto &rVar(r_var_loop.VarPtr);
    7119             :                         // Add to the total all of the appropriate variables
    7120     2178535 :                         InstantMeterValue += (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
    7121     2178535 :                         break;
    7122             :                     }
    7123             :                 }
    7124             :             }
    7125             : 
    7126    63433538 :             auto const &var_meter_on_custom(op->VarMeterArrays(Loop).OnCustomMeters);
    7127    63964194 :             for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnCustomMeters; Meter <= Meter_end; ++Meter) {
    7128      530656 :                 if (var_meter_on_custom(Meter) == energy_meter.SourceMeter) {
    7129             :                     // Separate the Zone variables from the HVAC variables using TimeStepType
    7130           0 :                     if (r_var_loop.timeStepType == t_timeStepType) {
    7131           0 :                         auto &rVar(r_var_loop.VarPtr);
    7132             :                         // Add to the total all of the appropriate variables
    7133           0 :                         InstantMeterValue += (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
    7134           0 :                         break;
    7135             :                     }
    7136             :                 }
    7137             :             }
    7138             : 
    7139             :         } // End Number of Meters Loop
    7140    63570754 :         for (int Loop = 1; Loop <= op->NumVarMeterArrays; ++Loop) {
    7141    63433538 :             auto &r_var_loop(op->RVariableTypes(op->VarMeterArrays(Loop).RepVariable));
    7142             : 
    7143    63433538 :             auto const &var_meter_on(op->VarMeterArrays(Loop).OnMeters);
    7144   389661342 :             for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnMeters; Meter <= Meter_end; ++Meter) {
    7145   326227804 :                 if (var_meter_on(Meter) == MeterNumber) {
    7146             :                     // Separate the Zone variables from the HVAC variables using TimeStepType
    7147           0 :                     if (r_var_loop.timeStepType == t_timeStepType) {
    7148           0 :                         auto &rVar(r_var_loop.VarPtr);
    7149             :                         // Add to the total all of the appropriate variables
    7150           0 :                         InstantMeterValue -= (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
    7151           0 :                         break;
    7152             :                     }
    7153             :                 }
    7154             :             }
    7155             : 
    7156    63433538 :             auto const &var_meter_on_custom(op->VarMeterArrays(Loop).OnCustomMeters);
    7157    63767474 :             for (int Meter = 1, Meter_end = op->VarMeterArrays(Loop).NumOnCustomMeters; Meter <= Meter_end; ++Meter) {
    7158      530656 :                 if (var_meter_on_custom(Meter) == MeterNumber) {
    7159             :                     // Separate the Zone variables from the HVAC variables using TimeStepType
    7160      393440 :                     if (r_var_loop.timeStepType == t_timeStepType) {
    7161      196720 :                         auto &rVar(r_var_loop.VarPtr);
    7162             :                         // Add to the total all of the appropriate variables
    7163      196720 :                         InstantMeterValue -= (*rVar.Which) * rVar.ZoneMult * rVar.ZoneListMult;
    7164      196720 :                         break;
    7165             :                     }
    7166             :                 }
    7167             :             }
    7168             : 
    7169             :         } // End Number of Meters Loop
    7170             :     }
    7171             : 
    7172    60242367 :     return InstantMeterValue;
    7173             : }
    7174             : 
    7175       23352 : void IncrementInstMeterCache(EnergyPlusData &state)
    7176             : {
    7177             :     // SUBROUTINE INFORMATION:
    7178             :     //       AUTHOR         Jason Glazer
    7179             :     //       DATE WRITTEN   January 2013
    7180             :     //       MODIFIED
    7181             :     //       RE-ENGINEERED  na
    7182             : 
    7183             :     // PURPOSE OF THIS FUNCTION:
    7184             :     // Manage the InstMeterCache array
    7185             : 
    7186             :     // METHODOLOGY EMPLOYED:
    7187             :     // When the array grows to large, double it.
    7188             : 
    7189       23352 :     auto &op(state.dataOutputProcessor);
    7190             : 
    7191       23352 :     if (!allocated(op->InstMeterCache)) {
    7192         746 :         op->InstMeterCache.dimension(op->InstMeterCacheSizeInc, 0); // zero the entire array
    7193         746 :         op->InstMeterCacheLastUsed = 1;
    7194             :     } else {
    7195       22606 :         ++op->InstMeterCacheLastUsed;
    7196             :         // if larger than current size grow the array
    7197       22606 :         if (op->InstMeterCacheLastUsed > op->InstMeterCacheSize) {
    7198           0 :             op->InstMeterCache.redimension(op->InstMeterCacheSize += op->InstMeterCacheSizeInc, 0);
    7199             :         }
    7200             :     }
    7201       23352 : }
    7202             : 
    7203    89026344 : Real64 GetInternalVariableValue(EnergyPlusData &state,
    7204             :                                 OutputProcessor::VariableType const varType, // 1=integer, 2=real, 3=meter
    7205             :                                 int const keyVarIndex                        // Array index
    7206             : )
    7207             : {
    7208             :     // FUNCTION INFORMATION:
    7209             :     //       AUTHOR         Linda K. Lawrie
    7210             :     //       DATE WRITTEN   December 2000
    7211             :     //       MODIFIED       August 2003, M. J. Witte
    7212             :     //       RE-ENGINEERED  na
    7213             : 
    7214             :     // PURPOSE OF THIS FUNCTION:
    7215             :     // This function returns the current value of the Internal Variable assigned to
    7216             :     // the varType and keyVarIndex.  Values may be accessed for REAL(r64) and integer
    7217             :     // report variables and meter variables.  The variable type (varType) may be
    7218             :     // determined by calling subroutine and GetVariableKeyCountandType.  The
    7219             :     // index (keyVarIndex) may be determined by calling subroutine GetVariableKeys.
    7220             : 
    7221             :     // METHODOLOGY EMPLOYED:
    7222             :     // Uses Internal OutputProcessor data structure to return value.
    7223             : 
    7224             :     // REFERENCES:
    7225             :     // na
    7226             : 
    7227             :     // Using/Aliasing
    7228             :     using namespace OutputProcessor;
    7229             :     using ScheduleManager::GetCurrentScheduleValue;
    7230             : 
    7231             :     // Return value
    7232             :     Real64 resultVal; // value returned
    7233             : 
    7234             :     // Locals
    7235             :     // FUNCTION ARGUMENT DEFINITIONS:
    7236             : 
    7237             :     // FUNCTION PARAMETER DEFINITIONS:
    7238             :     // na
    7239             : 
    7240             :     // INTERFACE BLOCK SPECIFICATIONS:
    7241             :     // na
    7242             : 
    7243             :     // DERIVED TYPE DEFINITIONS:
    7244             :     // na
    7245             : 
    7246             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    7247             :     // na
    7248             : 
    7249    89026344 :     auto &op(state.dataOutputProcessor);
    7250             : 
    7251             :     // Select based on variable type:  integer, real, or meter
    7252    89026344 :     if (varType == VariableType::NotFound) { // Variable not a found variable
    7253           0 :         resultVal = 0.0;
    7254    89026344 :     } else if (varType == VariableType::Integer) {
    7255       24135 :         if (keyVarIndex > op->NumOfIVariable) {
    7256           0 :             ShowFatalError(state, "GetInternalVariableValue: Integer variable passed index beyond range of array.");
    7257           0 :             ShowContinueError(state, format("Index = {} Number of integer variables = {}", keyVarIndex, op->NumOfIVariable));
    7258             :         }
    7259       24135 :         if (keyVarIndex < 1) {
    7260           0 :             ShowFatalError(state, format("GetInternalVariableValue: Integer variable passed index <1. Index = {}", keyVarIndex));
    7261             :         }
    7262             : 
    7263             :         // must use %Which, %Value is always zero if variable is not a requested report variable
    7264       24135 :         resultVal = double(*op->IVariableTypes(keyVarIndex).VarPtr.Which);
    7265    89002209 :     } else if (varType == VariableType::Real) {
    7266    88609601 :         if (keyVarIndex > op->NumOfRVariable) {
    7267           0 :             ShowFatalError(state, "GetInternalVariableValue: Real variable passed index beyond range of array.");
    7268           0 :             ShowContinueError(state, format("Index = {} Number of real variables = {}", keyVarIndex, op->NumOfRVariable));
    7269             :         }
    7270    88609601 :         if (keyVarIndex < 1) {
    7271           0 :             ShowFatalError(state, format("GetInternalVariableValue: Integer variable passed index <1. Index = {}", keyVarIndex));
    7272             :         }
    7273             : 
    7274             :         // must use %Which, %Value is always zero if variable is not a requested report variable
    7275    88609601 :         resultVal = *op->RVariableTypes(keyVarIndex).VarPtr.Which;
    7276      392608 :     } else if (varType == VariableType::Meter) {
    7277      392608 :         resultVal = GetCurrentMeterValue(state, keyVarIndex);
    7278           0 :     } else if (varType == VariableType::Schedule) {
    7279           0 :         resultVal = GetCurrentScheduleValue(state, keyVarIndex);
    7280             :     } else {
    7281           0 :         resultVal = 0.0;
    7282             :     }
    7283             : 
    7284    89026344 :     return resultVal;
    7285             : }
    7286             : 
    7287           0 : Real64 GetInternalVariableValueExternalInterface(EnergyPlusData &state,
    7288             :                                                  OutputProcessor::VariableType const varType, // 1=integer, 2=REAL(r64), 3=meter
    7289             :                                                  int const keyVarIndex                        // Array index
    7290             : )
    7291             : {
    7292             :     // FUNCTION INFORMATION:
    7293             :     //       AUTHOR         Thierry S. Nouidui
    7294             :     //       DATE WRITTEN   August 2011
    7295             :     //       MODIFIED       na
    7296             :     //       RE-ENGINEERED  na
    7297             : 
    7298             :     // PURPOSE OF THIS FUNCTION:
    7299             :     // This function returns the last zone-timestep value of the Internal Variable assigned to
    7300             :     // the varType and keyVarIndex.  Values may be accessed for REAL(r64) and integer
    7301             :     // report variables and meter variables.  The variable type (varType) may be
    7302             :     // determined by calling subroutine and GetVariableKeyCountandType.  The
    7303             :     // index (keyVarIndex) may be determined by calling subroutine GetVariableKeys.
    7304             : 
    7305             :     // METHODOLOGY EMPLOYED:
    7306             :     // Uses Internal OutputProcessor data structure to return value.
    7307             : 
    7308             :     // REFERENCES:
    7309             :     // na
    7310             : 
    7311             :     // Using/Aliasing
    7312             :     using namespace OutputProcessor;
    7313             :     using ScheduleManager::GetCurrentScheduleValue;
    7314             : 
    7315             :     // Return value
    7316             :     Real64 resultVal; // value returned
    7317             : 
    7318             :     // Locals
    7319             :     // FUNCTION ARGUMENT DEFINITIONS:
    7320             : 
    7321             :     // FUNCTION PARAMETER DEFINITIONS:
    7322             :     // na
    7323             : 
    7324             :     // INTERFACE BLOCK SPECIFICATIONS:
    7325             :     // na
    7326             : 
    7327             :     // DERIVED TYPE DEFINITIONS:
    7328             :     // na
    7329             : 
    7330             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    7331             :     // na
    7332             : 
    7333           0 :     auto &op(state.dataOutputProcessor);
    7334             : 
    7335             :     // Select based on variable type:  integer, REAL(r64), or meter
    7336           0 :     if (varType == VariableType::NotFound) { // Variable not a found variable
    7337           0 :         resultVal = 0.0;
    7338           0 :     } else if (varType == VariableType::Integer) {
    7339           0 :         if (keyVarIndex > op->NumOfIVariable) {
    7340           0 :             ShowFatalError(state, "GetInternalVariableValueExternalInterface: passed index beyond range of array.");
    7341             :         }
    7342           0 :         if (keyVarIndex < 1) {
    7343           0 :             ShowFatalError(state, "GetInternalVariableValueExternalInterface: passed index beyond range of array.");
    7344             :         }
    7345             : 
    7346             :         // must use %EITSValue, %This is the last-zonetimestep value
    7347           0 :         resultVal = double(op->IVariableTypes(keyVarIndex).VarPtr.EITSValue);
    7348           0 :     } else if (varType == VariableType::Real) {
    7349           0 :         if (keyVarIndex > op->NumOfRVariable) {
    7350           0 :             ShowFatalError(state, "GetInternalVariableValueExternalInterface: passed index beyond range of array.");
    7351             :         }
    7352           0 :         if (keyVarIndex < 1) {
    7353           0 :             ShowFatalError(state, "GetInternalVariableValueExternalInterface: passed index beyond range of array.");
    7354             :         }
    7355             : 
    7356             :         // must use %EITSValue, %This is the last-zonetimestep value
    7357           0 :         resultVal = op->RVariableTypes(keyVarIndex).VarPtr.EITSValue;
    7358           0 :     } else if (varType == VariableType::Meter) {
    7359           0 :         resultVal = GetCurrentMeterValue(state, keyVarIndex);
    7360           0 :     } else if (varType == VariableType::Schedule) {
    7361           0 :         resultVal = GetCurrentScheduleValue(state, keyVarIndex);
    7362             :     } else {
    7363           0 :         resultVal = 0.0;
    7364             :     }
    7365             : 
    7366           0 :     return resultVal;
    7367             : }
    7368             : 
    7369       32429 : int GetNumMeteredVariables(EnergyPlusData &state,
    7370             :                            [[maybe_unused]] std::string const &ComponentType, // Given Component Type
    7371             :                            std::string const &ComponentName                   // Given Component Name (user defined)
    7372             : )
    7373             : {
    7374             : 
    7375             :     // FUNCTION INFORMATION:
    7376             :     //       AUTHOR         Linda Lawrie
    7377             :     //       DATE WRITTEN   May 2005
    7378             :     //       MODIFIED       na
    7379             :     //       RE-ENGINEERED  na
    7380             : 
    7381             :     // PURPOSE OF THIS FUNCTION:
    7382             :     // This function counts the number of metered variables associated with the
    7383             :     // given ComponentType/Name.   This resultant number would then be used to
    7384             :     // allocate arrays for a call the GetMeteredVariables routine.
    7385             : 
    7386             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    7387             :     int Loop;
    7388       32429 :     int NumVariables = 0;
    7389       32429 :     auto &op(state.dataOutputProcessor);
    7390             : 
    7391    36392179 :     for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    7392             :         //    Pos=INDEX(RVariableTypes(Loop)%VarName,':')
    7393             :         //    IF (ComponentName /= RVariableTypes(Loop)%VarNameUC(1:Pos-1)) CYCLE
    7394    36359750 :         if (ComponentName != op->RVariableTypes(Loop).KeyNameOnlyUC) continue;
    7395       61167 :         auto &rVar(op->RVariableTypes(Loop).VarPtr);
    7396       61167 :         if (rVar.MeterArrayPtr == 0) {
    7397       24232 :             continue;
    7398             :         }
    7399       36935 :         if (op->VarMeterArrays(rVar.MeterArrayPtr).NumOnMeters > 0) {
    7400       36935 :             ++NumVariables;
    7401             :         }
    7402             :     }
    7403             : 
    7404       32429 :     return NumVariables;
    7405             : }
    7406             : 
    7407       16539 : void GetMeteredVariables(EnergyPlusData &state,
    7408             :                          std::string const &ComponentType,                                // Given Component Type
    7409             :                          std::string const &ComponentName,                                // Given Component Name (user defined)
    7410             :                          Array1D_int &VarIndexes,                                         // Variable Numbers
    7411             :                          Array1D<OutputProcessor::VariableType> &VarTypes,                // Variable Types (1=integer, 2=real, 3=meter)
    7412             :                          Array1D<OutputProcessor::TimeStepType> &TimeStepTypes,           // Variable Index Types (1=Zone,2=HVAC)
    7413             :                          Array1D<OutputProcessor::Unit> &unitsForVar,                     // units from enum for each variable
    7414             :                          std::map<int, DataGlobalConstants::ResourceType> &ResourceTypes, // ResourceTypes for each variable
    7415             :                          Array1D_string &EndUses,                                         // EndUses for each variable
    7416             :                          Array1D_string &Groups,                                          // Groups for each variable
    7417             :                          Array1D_string &Names,                                           // Variable Names for each variable
    7418             :                          int &NumFound                                                    // Number Found
    7419             : )
    7420             : {
    7421             : 
    7422             :     // SUBROUTINE INFORMATION:
    7423             :     //       AUTHOR         Linda Lawrie
    7424             :     //       DATE WRITTEN   May 2005
    7425             :     //       MODIFIED       Jason DeGraw 2/12/2020, de-optionalized
    7426             :     //       RE-ENGINEERED  na
    7427             : 
    7428             :     // PURPOSE OF THIS SUBROUTINE:
    7429             :     // This routine gets the variable names and other associated information
    7430             :     // for metered variables associated with the given ComponentType/Name.
    7431             : 
    7432             :     // Using/Aliasing
    7433             :     using namespace DataGlobalConstants;
    7434             :     using namespace OutputProcessor;
    7435             : 
    7436             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    7437             :     int Loop;
    7438             :     int NumVariables;
    7439             :     int MeterPtr;
    7440             :     int NumOnMeterPtr;
    7441             :     int MeterNum;
    7442       16539 :     auto &op(state.dataOutputProcessor);
    7443             : 
    7444       16539 :     NumVariables = 0;
    7445             : 
    7446    20875959 :     for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    7447             :         //    Pos=INDEX(RVariableTypes(Loop)%VarName,':')
    7448             :         //    IF (ComponentName /= RVariableTypes(Loop)%VarNameUC(1:Pos-1)) CYCLE
    7449    20859420 :         if (ComponentName != op->RVariableTypes(Loop).KeyNameOnlyUC) continue;
    7450       59074 :         auto &rVar(op->RVariableTypes(Loop).VarPtr);
    7451       59074 :         if (rVar.MeterArrayPtr == 0) continue;
    7452       36935 :         NumOnMeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).NumOnMeters;
    7453       36935 :         MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(1);
    7454       36935 :         if (MeterPtr) {
    7455       36935 :             ++NumVariables;
    7456       36935 :             VarIndexes(NumVariables) = Loop;
    7457       36935 :             VarTypes(NumVariables) = VariableType::Real;
    7458       36935 :             TimeStepTypes(NumVariables) = op->RVariableTypes(Loop).timeStepType;
    7459       36935 :             unitsForVar(NumVariables) = op->RVariableTypes(Loop).units;
    7460             : 
    7461       36935 :             ResourceTypes.at(NumVariables) = AssignResourceTypeNum(UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).ResourceType));
    7462             : 
    7463       36935 :             Names(NumVariables) = op->RVariableTypes(Loop).VarNameUC;
    7464             : 
    7465      110805 :             for (MeterNum = 1; MeterNum <= NumOnMeterPtr; ++MeterNum) {
    7466      110792 :                 MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(MeterNum);
    7467      110792 :                 if (!op->EnergyMeters(MeterPtr).EndUse.empty()) {
    7468       36922 :                     EndUses(NumVariables) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).EndUse);
    7469       36922 :                     break;
    7470             :                 }
    7471             :             }
    7472             : 
    7473       73870 :             for (MeterNum = 1; MeterNum <= NumOnMeterPtr; ++MeterNum) {
    7474       73870 :                 MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(MeterNum);
    7475       73870 :                 if (!op->EnergyMeters(MeterPtr).Group.empty()) {
    7476       36935 :                     Groups(NumVariables) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).Group);
    7477       36935 :                     break;
    7478             :                 }
    7479             :             }
    7480             : 
    7481             :         } else {
    7482           0 :             ShowWarningError(state,
    7483           0 :                              "Referenced variable or meter used in the wrong context \"" + ComponentName + "\" of type \"" + ComponentType + "\"");
    7484             :         }
    7485             :     }
    7486             : 
    7487       16539 :     NumFound = NumVariables; // Should just return this
    7488       16539 : }
    7489             : 
    7490           0 : void GetMeteredVariables(EnergyPlusData &state,
    7491             :                          std::string const &ComponentType,                                // Given Component Type
    7492             :                          std::string const &ComponentName,                                // Given Component Name (user defined)
    7493             :                          Array1D_int &VarIndexes,                                         // Variable Numbers
    7494             :                          Array1D<OutputProcessor::VariableType> &VarTypes,                // Variable Types (1=integer, 2=real, 3=meter)
    7495             :                          Array1D<OutputProcessor::TimeStepType> &TimeStepTypes,           // Variable Index Types (1=Zone,2=HVAC)
    7496             :                          Array1D<OutputProcessor::Unit> &unitsForVar,                     // units from enum for each variable
    7497             :                          std::map<int, DataGlobalConstants::ResourceType> &ResourceTypes, // ResourceTypes for each variable
    7498             :                          Array1D_string &EndUses,                                         // EndUses for each variable
    7499             :                          Array1D_string &Groups,                                          // Groups for each variable
    7500             :                          Array1D_string &Names,                                           // Variable Names for each variable
    7501             :                          Array1D_int &VarIDs                                              // Variable Report Numbers
    7502             : )
    7503             : {
    7504             : 
    7505             :     // SUBROUTINE INFORMATION:
    7506             :     //       AUTHOR         Linda Lawrie
    7507             :     //       DATE WRITTEN   May 2005
    7508             :     //       MODIFIED       Jason DeGraw 2/12/2020, de-optionalized
    7509             :     //       RE-ENGINEERED  na
    7510             : 
    7511             :     // PURPOSE OF THIS SUBROUTINE:
    7512             :     // This routine gets the variable names and other associated information
    7513             :     // for metered variables associated with the given ComponentType/Name.
    7514             : 
    7515             :     // Using/Aliasing
    7516             :     using namespace DataGlobalConstants;
    7517             :     using namespace OutputProcessor;
    7518             : 
    7519             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    7520             :     int Loop;
    7521             :     int NumVariables;
    7522             :     int MeterPtr;
    7523             :     int NumOnMeterPtr;
    7524             :     int MeterNum;
    7525           0 :     auto &op(state.dataOutputProcessor);
    7526             : 
    7527           0 :     NumVariables = 0;
    7528             : 
    7529           0 :     for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    7530             :         //    Pos=INDEX(RVariableTypes(Loop)%VarName,':')
    7531             :         //    IF (ComponentName /= RVariableTypes(Loop)%VarNameUC(1:Pos-1)) CYCLE
    7532           0 :         if (ComponentName != op->RVariableTypes(Loop).KeyNameOnlyUC) continue;
    7533           0 :         auto &rVar(op->RVariableTypes(Loop).VarPtr);
    7534           0 :         if (rVar.MeterArrayPtr == 0) continue;
    7535           0 :         NumOnMeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).NumOnMeters;
    7536           0 :         MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(1);
    7537           0 :         if (MeterPtr) {
    7538           0 :             ++NumVariables;
    7539           0 :             VarIndexes(NumVariables) = Loop;
    7540           0 :             VarTypes(NumVariables) = VariableType::Real;
    7541           0 :             TimeStepTypes(NumVariables) = op->RVariableTypes(Loop).timeStepType;
    7542           0 :             unitsForVar(NumVariables) = op->RVariableTypes(Loop).units;
    7543             : 
    7544           0 :             ResourceTypes.at(NumVariables) = AssignResourceTypeNum(UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).ResourceType));
    7545           0 :             Names(NumVariables) = op->RVariableTypes(Loop).VarNameUC;
    7546             : 
    7547           0 :             for (MeterNum = 1; MeterNum <= NumOnMeterPtr; ++MeterNum) {
    7548           0 :                 MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(MeterNum);
    7549           0 :                 if (!op->EnergyMeters(MeterPtr).EndUse.empty()) {
    7550           0 :                     EndUses(NumVariables) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).EndUse);
    7551           0 :                     break;
    7552             :                 }
    7553             :             }
    7554             : 
    7555           0 :             for (MeterNum = 1; MeterNum <= NumOnMeterPtr; ++MeterNum) {
    7556           0 :                 MeterPtr = op->VarMeterArrays(rVar.MeterArrayPtr).OnMeters(MeterNum);
    7557           0 :                 if (!op->EnergyMeters(MeterPtr).Group.empty()) {
    7558           0 :                     Groups(NumVariables) = UtilityRoutines::MakeUPPERCase(op->EnergyMeters(MeterPtr).Group);
    7559           0 :                     break;
    7560             :                 }
    7561             :             }
    7562             : 
    7563           0 :             VarIDs(NumVariables) = rVar.ReportID;
    7564             : 
    7565             :         } else {
    7566           0 :             ShowWarningError(state,
    7567           0 :                              "Referenced variable or meter used in the wrong context \"" + ComponentName + "\" of type \"" + ComponentType + "\"");
    7568             :         }
    7569             :     }
    7570           0 : }
    7571             : 
    7572       58393 : void GetVariableKeyCountandType(EnergyPlusData &state,
    7573             :                                 std::string const &varName, // Standard variable name
    7574             :                                 int &numKeys,               // Number of keys found
    7575             :                                 OutputProcessor::VariableType &varType,
    7576             :                                 OutputProcessor::StoreType &varAvgSum,      // Variable  is Averaged=1 or Summed=2
    7577             :                                 OutputProcessor::TimeStepType &varStepType, // Variable time step is Zone=1 or HVAC=2
    7578             :                                 OutputProcessor::Unit &varUnits             // Units enumeration
    7579             : )
    7580             : {
    7581             : 
    7582             :     // SUBROUTINE INFORMATION:
    7583             :     //       AUTHOR         Michael J. Witte
    7584             :     //       DATE WRITTEN   August 2003
    7585             :     //       MODIFIED       na
    7586             :     //       RE-ENGINEERED  na
    7587             : 
    7588             :     // PURPOSE OF THIS SUBROUTINE:
    7589             :     // This subroutine returns the variable TYPE (Real, integer, meter, schedule, etc.)
    7590             :     // (varType) whether it is an averaged or summed variable (varAvgSum),
    7591             :     // whether it is a zone or HVAC time step (varStepType),
    7592             :     // and the number of keynames for a given report variable or report meter name
    7593             :     // (varName).  The variable type (varType) and number of keys (numKeys) are
    7594             :     // used when calling subroutine GetVariableKeys to obtain a list of the
    7595             :     // keynames for a particular variable and a corresponding list of indexes.
    7596             : 
    7597             :     // METHODOLOGY EMPLOYED:
    7598             :     // Uses Internal OutputProcessor data structure to search for varName
    7599             :     // in each of the three output data arrays:
    7600             :     //       RVariableTypes - real report variables
    7601             :     //       IVariableTypes - integer report variables
    7602             :     //       EnergyMeters   - report meters (via GetMeterIndex function)
    7603             :     //       Schedules      - specific schedule values
    7604             :     // When the variable is found, the variable type (varType) is set and the
    7605             :     // number of associated keys is counted.
    7606             :     // varType is assigned as follows:
    7607             :     //       0 = not found
    7608             :     //       1 = integer
    7609             :     //       2 = real
    7610             :     //       3 = meter
    7611             :     //       4 = schedule
    7612             :     //  varAvgSum is assigned as follows:
    7613             :     //       1 = averaged
    7614             :     //       2 = summed
    7615             :     //  varStepType is assigned as follows:
    7616             :     //       1 = zone time step
    7617             :     //       2 = HVAC time step
    7618             : 
    7619             :     // Using/Aliasing
    7620             :     using namespace OutputProcessor;
    7621             :     using ScheduleManager::GetScheduleIndex;
    7622             :     using ScheduleManager::GetScheduleType;
    7623             :     using SortAndStringUtilities::SetupAndSort;
    7624             : 
    7625             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    7626             :     int Loop; // Loop counters
    7627             :     int Loop2;
    7628             :     std::string::size_type Position; // Starting point of search string
    7629             :     int VFound;                      // Found integer/real variable attributes
    7630             :     bool Found;                      // True if varName is found
    7631             :     bool Duplicate;                  // True if keyname is a duplicate
    7632      116786 :     std::string VarKeyPlusName;      // Full variable name including keyname and units
    7633      116786 :     std::string varNameUpper;        // varName pushed to all upper case
    7634       58393 :     auto &op(state.dataOutputProcessor);
    7635             : 
    7636             :     // INITIALIZATIONS
    7637       58393 :     if (op->InitFlag) {
    7638         167 :         op->curKeyVarIndexLimit = 1000;
    7639         167 :         op->keyVarIndexes.allocate(op->curKeyVarIndexLimit);
    7640         167 :         op->numVarNames = op->NumVariablesForOutput;
    7641         167 :         op->varNames.allocate(op->numVarNames);
    7642       91244 :         for (Loop = 1; Loop <= op->NumVariablesForOutput; ++Loop) {
    7643       91077 :             op->varNames(Loop) = UtilityRoutines::MakeUPPERCase(op->DDVariableTypes(Loop).VarNameOnly);
    7644             :         }
    7645         167 :         op->ivarNames.allocate(op->numVarNames);
    7646         167 :         SetupAndSort(op->varNames, op->ivarNames);
    7647         167 :         op->InitFlag = false;
    7648             :     }
    7649             : 
    7650       58393 :     if (op->numVarNames != op->NumVariablesForOutput) {
    7651         349 :         op->numVarNames = op->NumVariablesForOutput;
    7652         349 :         op->varNames.allocate(op->numVarNames);
    7653      163272 :         for (Loop = 1; Loop <= op->NumVariablesForOutput; ++Loop) {
    7654      162923 :             op->varNames(Loop) = UtilityRoutines::MakeUPPERCase(op->DDVariableTypes(Loop).VarNameOnly);
    7655             :         }
    7656         349 :         op->ivarNames.allocate(op->numVarNames);
    7657         349 :         SetupAndSort(op->varNames, op->ivarNames);
    7658             :     }
    7659             : 
    7660       58393 :     op->keyVarIndexes = 0;
    7661       58393 :     varType = VariableType::NotFound;
    7662       58393 :     numKeys = 0;
    7663       58393 :     varAvgSum = StoreType::Averaged;
    7664       58393 :     varStepType = TimeStepType::Zone;
    7665       58393 :     varUnits = OutputProcessor::Unit::None;
    7666       58393 :     Found = false;
    7667       58393 :     Duplicate = false;
    7668       58393 :     varNameUpper = varName;
    7669             : 
    7670             :     // Search Variable List First
    7671       58393 :     VFound = UtilityRoutines::FindItemInSortedList(varNameUpper, op->varNames, op->numVarNames);
    7672       58393 :     if (VFound != 0) {
    7673        2113 :         varType = op->DDVariableTypes(op->ivarNames(VFound)).variableType;
    7674             :     }
    7675             : 
    7676       58393 :     if (varType == VariableType::Integer) {
    7677             :         // Search Integer Variables
    7678          30 :         for (Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    7679          25 :             VarKeyPlusName = op->IVariableTypes(Loop).VarNameUC;
    7680          25 :             Position = index(VarKeyPlusName, ':' + varNameUpper, true);
    7681          25 :             if (Position != std::string::npos) {
    7682          25 :                 if (VarKeyPlusName.substr(Position + 1) == varNameUpper) {
    7683          25 :                     Found = true;
    7684          25 :                     varType = VariableType::Integer;
    7685          25 :                     Duplicate = false;
    7686             :                     // Check if duplicate - duplicates happen if the same report variable/key name
    7687             :                     // combination is requested more than once in the idf at different reporting
    7688             :                     // frequencies
    7689          75 :                     for (Loop2 = 1; Loop2 <= numKeys; ++Loop2) {
    7690          50 :                         if (VarKeyPlusName == op->IVariableTypes(op->keyVarIndexes(Loop2)).VarNameUC) Duplicate = true;
    7691             :                     }
    7692          25 :                     if (!Duplicate) {
    7693          25 :                         ++numKeys;
    7694          25 :                         if (numKeys > op->curKeyVarIndexLimit) {
    7695           0 :                             op->keyVarIndexes.redimension(op->curKeyVarIndexLimit += 500, 0);
    7696             :                         }
    7697          25 :                         op->keyVarIndexes(numKeys) = Loop;
    7698          25 :                         varAvgSum = op->DDVariableTypes(op->ivarNames(VFound)).storeType;
    7699          25 :                         varStepType = op->DDVariableTypes(op->ivarNames(VFound)).timeStepType;
    7700          25 :                         varUnits = op->DDVariableTypes(op->ivarNames(VFound)).units;
    7701             :                     }
    7702             :                 }
    7703             :             }
    7704             :         }
    7705       58388 :     } else if (varType == VariableType::Real) {
    7706             :         // Search real Variables Next
    7707     2193293 :         for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    7708     2191185 :             if (op->RVariableTypes(Loop).VarNameOnlyUC == varNameUpper) {
    7709      152072 :                 Found = true;
    7710      152072 :                 varType = VariableType::Real;
    7711      152072 :                 Duplicate = false;
    7712             :                 // Check if duplicate - duplicates happen if the same report variable/key name
    7713             :                 // combination is requested more than once in the idf at different reporting
    7714             :                 // frequencies
    7715      152072 :                 VarKeyPlusName = op->RVariableTypes(Loop).VarNameUC;
    7716    14364330 :                 for (Loop2 = 1; Loop2 <= numKeys; ++Loop2) {
    7717    14212258 :                     if (VarKeyPlusName == op->RVariableTypes(op->keyVarIndexes(Loop2)).VarNameUC) Duplicate = true;
    7718             :                 }
    7719      152072 :                 if (!Duplicate) {
    7720      152072 :                     ++numKeys;
    7721      152072 :                     if (numKeys > op->curKeyVarIndexLimit) {
    7722           0 :                         op->keyVarIndexes.redimension(op->curKeyVarIndexLimit += 500, 0);
    7723             :                     }
    7724      152072 :                     op->keyVarIndexes(numKeys) = Loop;
    7725      152072 :                     varAvgSum = op->DDVariableTypes(op->ivarNames(VFound)).storeType;
    7726      152072 :                     varStepType = op->DDVariableTypes(op->ivarNames(VFound)).timeStepType;
    7727      152072 :                     varUnits = op->DDVariableTypes(op->ivarNames(VFound)).units;
    7728             :                 }
    7729             :             }
    7730             :         }
    7731             :     }
    7732             : 
    7733             :     // Search Meters if not found in integers or reals
    7734             :     // Use the GetMeterIndex function
    7735             :     // Meters do not have keys, so only one will be found
    7736       58393 :     if (!Found) {
    7737       56280 :         op->keyVarIndexes(1) = GetMeterIndex(state, varName);
    7738       56280 :         if (op->keyVarIndexes(1) > 0) {
    7739         367 :             Found = true;
    7740         367 :             numKeys = 1;
    7741         367 :             varType = VariableType::Meter;
    7742         367 :             varUnits = op->EnergyMeters(op->keyVarIndexes(1)).Units;
    7743         367 :             varAvgSum = StoreType::Summed;
    7744         367 :             varStepType = TimeStepType::Zone;
    7745             :         }
    7746             :     }
    7747             : 
    7748             :     // Search schedules if not found in integers, reals, or meters
    7749             :     // Use the GetScheduleIndex function
    7750             :     // Schedules do not have keys, so only one will be found
    7751       58393 :     if (!Found) {
    7752       55913 :         op->keyVarIndexes(1) = GetScheduleIndex(state, varName);
    7753       55913 :         if (op->keyVarIndexes(1) > 0) {
    7754           0 :             Found = true;
    7755           0 :             numKeys = 1;
    7756           0 :             varType = VariableType::Schedule;
    7757           0 :             varUnits = unitStringToEnum(GetScheduleType(state, op->keyVarIndexes(1)));
    7758           0 :             varAvgSum = StoreType::Averaged;
    7759           0 :             varStepType = TimeStepType::Zone;
    7760             :         }
    7761             :     }
    7762       58393 : }
    7763             : 
    7764        2480 : void GetVariableKeys(EnergyPlusData &state,
    7765             :                      std::string const &varName,                  // Standard variable name
    7766             :                      OutputProcessor::VariableType const varType, // 1=integer, 2=real, 3=meter
    7767             :                      Array1D_string &keyNames,                    // Specific key name
    7768             :                      Array1D_int &keyVarIndexes                   // Array index for
    7769             : )
    7770             : {
    7771             : 
    7772             :     // SUBROUTINE INFORMATION:
    7773             :     //       AUTHOR         Michael J. Witte
    7774             :     //       DATE WRITTEN   August 2003
    7775             :     //       MODIFIED       na
    7776             :     //       RE-ENGINEERED  na
    7777             : 
    7778             :     // PURPOSE OF THIS SUBROUTINE:
    7779             :     // This subroutine returns a list of keynames and indexes associated
    7780             :     // with a particular report variable or report meter name (varName).
    7781             :     // This routine assumes that the variable TYPE (Real, integer, meter, etc.)
    7782             :     // may be determined by calling GetVariableKeyCountandType.  The variable type
    7783             :     // and index can then be used with function GetInternalVariableValue to
    7784             :     // to retrieve the current value of a particular variable/keyname combination.
    7785             : 
    7786             :     // METHODOLOGY EMPLOYED:
    7787             :     // Uses Internal OutputProcessor data structure to search for varName
    7788             :     // and build list of keynames and indexes.  The indexes are the array index
    7789             :     // in the data array for the
    7790             : 
    7791             :     // Using/Aliasing
    7792             :     using namespace OutputProcessor;
    7793             :     using ScheduleManager::GetScheduleIndex;
    7794             : 
    7795             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    7796             :     int Loop; // Loop counters
    7797             :     int Loop2;
    7798             :     std::string::size_type Position; // Starting point of search string
    7799             :     bool Duplicate;                  // True if keyname is a duplicate
    7800             :     int maxKeyNames;                 // Max allowable # of key names=size of keyNames array
    7801             :     int maxkeyVarIndexes;            // Max allowable # of key indexes=size of keyVarIndexes array
    7802             :     int numKeys;                     // Number of keys found
    7803        4960 :     std::string VarKeyPlusName;      // Full variable name including keyname and units
    7804        4960 :     std::string varNameUpper;        // varName pushed to all upper case
    7805             : 
    7806             :     // INITIALIZATIONS
    7807        2480 :     keyNames = "";
    7808        2480 :     keyVarIndexes = 0;
    7809        2480 :     numKeys = 0;
    7810        2480 :     Duplicate = false;
    7811        2480 :     maxKeyNames = size(keyNames);
    7812        2480 :     maxkeyVarIndexes = size(keyVarIndexes);
    7813        2480 :     varNameUpper = UtilityRoutines::MakeUPPERCase(varName);
    7814        2480 :     auto &op(state.dataOutputProcessor);
    7815             : 
    7816             :     // Select based on variable type:  integer, real, or meter
    7817        2480 :     if (varType == VariableType::Integer) { // Integer
    7818          30 :         for (Loop = 1; Loop <= op->NumOfIVariable; ++Loop) {
    7819          25 :             VarKeyPlusName = op->IVariableTypes(Loop).VarNameUC;
    7820          25 :             Position = index(VarKeyPlusName, ':' + varNameUpper, true);
    7821          25 :             if (Position != std::string::npos) {
    7822          25 :                 if (VarKeyPlusName.substr(Position + 1) == varNameUpper) {
    7823          25 :                     Duplicate = false;
    7824             :                     // Check if duplicate - duplicates happen if the same report variable/key name
    7825             :                     // combination is requested more than once in the idf at different reporting
    7826             :                     // frequencies
    7827          75 :                     for (Loop2 = 1; Loop2 <= numKeys; ++Loop2) {
    7828          50 :                         if (VarKeyPlusName == op->IVariableTypes(keyVarIndexes(Loop2)).VarNameUC) Duplicate = true;
    7829             :                     }
    7830          25 :                     if (!Duplicate) {
    7831          25 :                         ++numKeys;
    7832          25 :                         if ((numKeys > maxKeyNames) || (numKeys > maxkeyVarIndexes)) {
    7833           0 :                             ShowFatalError(state, "Invalid array size in GetVariableKeys");
    7834             :                         }
    7835          25 :                         keyNames(numKeys) = op->IVariableTypes(Loop).VarNameUC.substr(0, Position);
    7836          25 :                         keyVarIndexes(numKeys) = Loop;
    7837             :                     }
    7838             :                 }
    7839             :             }
    7840             :         }
    7841        2475 :     } else if (varType == VariableType::Real) { // Real
    7842     2193293 :         for (Loop = 1; Loop <= op->NumOfRVariable; ++Loop) {
    7843     2191185 :             if (op->RVariableTypes(Loop).VarNameOnlyUC == varNameUpper) {
    7844      152072 :                 Duplicate = false;
    7845             :                 // Check if duplicate - duplicates happen if the same report variable/key name
    7846             :                 // combination is requested more than once in the idf at different reporting
    7847             :                 // frequencies
    7848      152072 :                 VarKeyPlusName = op->RVariableTypes(Loop).VarNameUC;
    7849    14364330 :                 for (Loop2 = 1; Loop2 <= numKeys; ++Loop2) {
    7850    14212258 :                     if (VarKeyPlusName == op->RVariableTypes(keyVarIndexes(Loop2)).VarNameUC) Duplicate = true;
    7851             :                 }
    7852      152072 :                 if (!Duplicate) {
    7853      152072 :                     ++numKeys;
    7854      152072 :                     if ((numKeys > maxKeyNames) || (numKeys > maxkeyVarIndexes)) {
    7855           0 :                         ShowFatalError(state, "Invalid array size in GetVariableKeys");
    7856             :                     }
    7857      152072 :                     keyNames(numKeys) = op->RVariableTypes(Loop).KeyNameOnlyUC;
    7858      152072 :                     keyVarIndexes(numKeys) = Loop;
    7859             :                 }
    7860             :             }
    7861             :         }
    7862         367 :     } else if (varType == VariableType::Meter) { // Meter
    7863         367 :         numKeys = 1;
    7864         367 :         if ((numKeys > maxKeyNames) || (numKeys > maxkeyVarIndexes)) {
    7865           0 :             ShowFatalError(state, "Invalid array size in GetVariableKeys");
    7866             :         }
    7867         367 :         keyNames(1) = "Meter";
    7868         367 :         keyVarIndexes(1) = GetMeterIndex(state, varName);
    7869           0 :     } else if (varType == VariableType::Schedule) { // Schedule
    7870           0 :         numKeys = 1;
    7871           0 :         if ((numKeys > maxKeyNames) || (numKeys > maxkeyVarIndexes)) {
    7872           0 :             ShowFatalError(state, "Invalid array size in GetVariableKeys");
    7873             :         }
    7874           0 :         keyNames(1) = "Environment";
    7875           0 :         keyVarIndexes(1) = GetScheduleIndex(state, varName);
    7876             :     } else {
    7877             :         // do nothing
    7878             :     }
    7879        2480 : }
    7880             : 
    7881        8113 : bool ReportingThisVariable(EnergyPlusData &state, std::string const &RepVarName)
    7882             : {
    7883             : 
    7884             :     // FUNCTION INFORMATION:
    7885             :     //       AUTHOR         Linda Lawrie
    7886             :     //       DATE WRITTEN   October 2008
    7887             :     //       MODIFIED       na
    7888             :     //       RE-ENGINEERED  na
    7889             : 
    7890             :     // PURPOSE OF THIS FUNCTION:
    7891             :     // This function scans the report variables and reports back
    7892             :     // if user has requested this variable be reported.
    7893             : 
    7894             :     // METHODOLOGY EMPLOYED:
    7895             :     // na
    7896             : 
    7897             :     // REFERENCES:
    7898             :     // na
    7899             : 
    7900             :     // Using/Aliasing
    7901             :     using namespace OutputProcessor;
    7902             : 
    7903             :     // Return value
    7904             :     bool BeingReported;
    7905             : 
    7906             :     // Locals
    7907             :     // FUNCTION ARGUMENT DEFINITIONS:
    7908             : 
    7909             :     // FUNCTION PARAMETER DEFINITIONS:
    7910             :     // na
    7911             : 
    7912             :     // INTERFACE BLOCK SPECIFICATIONS:
    7913             :     // na
    7914             : 
    7915             :     // DERIVED TYPE DEFINITIONS:
    7916             :     // na
    7917             : 
    7918             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    7919             :     int Found;
    7920        8113 :     auto &op(state.dataOutputProcessor);
    7921             : 
    7922        8113 :     BeingReported = false;
    7923        8113 :     Found = UtilityRoutines::FindItem(RepVarName, op->ReqRepVars, &ReqReportVariables::VarName);
    7924        8113 :     if (Found > 0) {
    7925           0 :         BeingReported = true;
    7926             :     }
    7927             : 
    7928        8113 :     if (!BeingReported) { // check meter names too
    7929        8113 :         Found = UtilityRoutines::FindItem(RepVarName, op->EnergyMeters);
    7930        8113 :         if (Found > 0) {
    7931        5569 :             if (op->EnergyMeters(Found).RptTS || op->EnergyMeters(Found).RptHR || op->EnergyMeters(Found).RptDY || op->EnergyMeters(Found).RptMN ||
    7932        4170 :                 op->EnergyMeters(Found).RptSM || op->EnergyMeters(Found).RptTSFO || op->EnergyMeters(Found).RptHRFO ||
    7933        4170 :                 op->EnergyMeters(Found).RptDYFO || op->EnergyMeters(Found).RptMNFO || op->EnergyMeters(Found).RptSMFO ||
    7934        4170 :                 op->EnergyMeters(Found).RptAccTS || op->EnergyMeters(Found).RptAccHR || op->EnergyMeters(Found).RptAccDY ||
    7935        4170 :                 op->EnergyMeters(Found).RptAccMN || op->EnergyMeters(Found).RptAccSM || op->EnergyMeters(Found).RptAccTSFO ||
    7936        5563 :                 op->EnergyMeters(Found).RptAccHRFO || op->EnergyMeters(Found).RptAccDYFO || op->EnergyMeters(Found).RptAccMNFO ||
    7937        1390 :                 op->EnergyMeters(Found).RptAccSMFO) {
    7938           3 :                 BeingReported = true;
    7939             :             }
    7940             :         }
    7941             :     }
    7942             : 
    7943        8113 :     return BeingReported;
    7944             : }
    7945             : 
    7946          60 : void InitPollutionMeterReporting(EnergyPlusData &state, std::string const &ReportFreqName)
    7947             : {
    7948             : 
    7949             :     // SUBROUTINE INFORMATION:Richard Liesen
    7950             :     //       DATE WRITTEN   July 2002
    7951             :     //       MODIFIED       na
    7952             :     //       RE-ENGINEERED  na
    7953             : 
    7954             :     // PURPOSE OF THIS SUBROUTINE:
    7955             :     // This subroutine is called at the end of the first HVAC iteration and
    7956             :     // sets up the reporting for the Pollution Meters.
    7957             :     // ReportPollutionOutput,
    7958             :     //   A1 ; \field Reporting_Frequency
    7959             :     //        \type choice
    7960             :     //        \key timestep
    7961             :     //        \key hourly
    7962             :     //        \key daily
    7963             :     //        \key monthly
    7964             :     //        \key runperiod
    7965             :     // METHODOLOGY EMPLOYED:
    7966             :     // The program tries to setup all of the following meters if the Pollution Report is initiated.
    7967             :     //       Electricity:Facility [J]
    7968             :     //       Diesel:Facility [J]
    7969             :     //       DistrictCooling:Facility [J]
    7970             :     //       DistrictHeating:Facility [J]
    7971             :     //       Gas:Facility [J]
    7972             :     //       GASOLINE:Facility [J]
    7973             :     //       COAL:Facility [J]
    7974             :     //       FuelOilNo1:Facility [J]
    7975             :     //       FuelOilNo2:Facility [J]
    7976             :     //       Propane:Facility [J]
    7977             :     //       ElectricityProduced:Facility [J]
    7978             :     //       Pollutant:CO2
    7979             :     //       Pollutant:CO
    7980             :     //       Pollutant:CH4
    7981             :     //       Pollutant:NOx
    7982             :     //       Pollutant:N2O
    7983             :     //       Pollutant:SO2
    7984             :     //       Pollutant:PM
    7985             :     //       Pollutant:PM10
    7986             :     //       Pollutant:PM2.5
    7987             :     //       Pollutant:NH3
    7988             :     //       Pollutant:NMVOC
    7989             :     //       Pollutant:Hg
    7990             :     //       Pollutant:Pb
    7991             :     //       Pollutant:WaterEnvironmentalFactors
    7992             :     //       Pollutant:Nuclear High
    7993             :     //       Pollutant:Nuclear Low
    7994             :     //       Pollutant:Carbon Equivalent
    7995             : 
    7996             :     // Using/Aliasing
    7997             :     using namespace OutputProcessor;
    7998             :     // SUBROUTINE PARAMETER DEFINITIONS:
    7999             :     //             Now for the Pollution Meters
    8000             :     static Array1D_string const PollutionMeters({1, 29},
    8001             :                                                 {"Electricity:Facility",
    8002             :                                                  "Diesel:Facility",
    8003             :                                                  "DistrictCooling:Facility",
    8004             :                                                  "DistrictHeating:Facility",
    8005             :                                                  "NaturalGas:Facility",
    8006             :                                                  "GASOLINE:Facility",
    8007             :                                                  "COAL:Facility",
    8008             :                                                  "FuelOilNo1:Facility",
    8009             :                                                  "FuelOilNo2:Facility",
    8010             :                                                  "Propane:Facility",
    8011             :                                                  "ElectricityProduced:Facility",
    8012             :                                                  "Steam:Facility",
    8013             :                                                  "CO2:Facility",
    8014             :                                                  "CO:Facility",
    8015             :                                                  "CH4:Facility",
    8016             :                                                  "NOx:Facility",
    8017             :                                                  "N2O:Facility",
    8018             :                                                  "SO2:Facility",
    8019             :                                                  "PM:Facility",
    8020             :                                                  "PM10:Facility",
    8021             :                                                  "PM2.5:Facility",
    8022             :                                                  "NH3:Facility",
    8023             :                                                  "NMVOC:Facility",
    8024             :                                                  "Hg:Facility",
    8025             :                                                  "Pb:Facility",
    8026             :                                                  "WaterEnvironmentalFactors:Facility",
    8027             :                                                  "Nuclear High:Facility",
    8028             :                                                  "Nuclear Low:Facility",
    8029          60 :                                                  "Carbon Equivalent:Facility"});
    8030             : 
    8031             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    8032             :     int Loop;
    8033             :     int NumReqMeters;
    8034             :     int Meter;
    8035          60 :     ReportingFrequency ReportFreq(determineFrequency(state, ReportFreqName));
    8036             : 
    8037             :     int indexGroupKey;
    8038         120 :     std::string indexGroup;
    8039          60 :     auto &op(state.dataOutputProcessor);
    8040             : 
    8041          60 :     NumReqMeters = 29;
    8042             : 
    8043        1800 :     for (Loop = 1; Loop <= NumReqMeters; ++Loop) {
    8044             : 
    8045        1740 :         Meter = UtilityRoutines::FindItem(PollutionMeters(Loop), op->EnergyMeters);
    8046        1740 :         if (Meter > 0) { // All the active meters for this run are set, but all are still searched for.
    8047             : 
    8048        1150 :             indexGroupKey = DetermineIndexGroupKeyFromMeterName(state, op->EnergyMeters(Meter).Name);
    8049        1150 :             indexGroup = DetermineIndexGroupFromMeterGroup(op->EnergyMeters(Meter));
    8050             :             // All of the specified meters are checked and the headers printed to the meter file if this
    8051             :             //  has not been done previously
    8052        1150 :             if (ReportFreq == ReportingFrequency::TimeStep) {
    8053           0 :                 if (op->EnergyMeters(Meter).RptTS) {
    8054           0 :                     op->EnergyMeters(Meter).RptTS = true;
    8055             :                 } else {
    8056           0 :                     op->EnergyMeters(Meter).RptTS = true;
    8057           0 :                     WriteMeterDictionaryItem(state,
    8058             :                                              ReportFreq,
    8059             :                                              StoreType::Summed,
    8060           0 :                                              op->EnergyMeters(Meter).TSRptNum,
    8061             :                                              indexGroupKey,
    8062             :                                              indexGroup,
    8063           0 :                                              op->EnergyMeters(Meter).TSRptNumChr,
    8064           0 :                                              op->EnergyMeters(Meter).Name,
    8065           0 :                                              op->EnergyMeters(Meter).Units,
    8066             :                                              false,
    8067             :                                              false);
    8068             :                 }
    8069        1150 :             } else if (ReportFreq == ReportingFrequency::Hourly) {
    8070           0 :                 if (op->EnergyMeters(Meter).RptHR) {
    8071           0 :                     op->EnergyMeters(Meter).RptHR = true;
    8072           0 :                     op->TrackingHourlyVariables = true;
    8073             :                 } else {
    8074           0 :                     op->EnergyMeters(Meter).RptHR = true;
    8075           0 :                     op->TrackingHourlyVariables = true;
    8076           0 :                     WriteMeterDictionaryItem(state,
    8077             :                                              ReportFreq,
    8078             :                                              StoreType::Summed,
    8079           0 :                                              op->EnergyMeters(Meter).HRRptNum,
    8080             :                                              indexGroupKey,
    8081             :                                              indexGroup,
    8082           0 :                                              op->EnergyMeters(Meter).HRRptNumChr,
    8083           0 :                                              op->EnergyMeters(Meter).Name,
    8084           0 :                                              op->EnergyMeters(Meter).Units,
    8085             :                                              false,
    8086             :                                              false);
    8087             :                 }
    8088        1150 :             } else if (ReportFreq == ReportingFrequency::Daily) {
    8089           0 :                 if (op->EnergyMeters(Meter).RptDY) {
    8090           0 :                     op->EnergyMeters(Meter).RptDY = true;
    8091           0 :                     op->TrackingDailyVariables = true;
    8092             :                 } else {
    8093           0 :                     op->EnergyMeters(Meter).RptDY = true;
    8094           0 :                     op->TrackingDailyVariables = true;
    8095           0 :                     WriteMeterDictionaryItem(state,
    8096             :                                              ReportFreq,
    8097             :                                              StoreType::Summed,
    8098           0 :                                              op->EnergyMeters(Meter).DYRptNum,
    8099             :                                              indexGroupKey,
    8100             :                                              indexGroup,
    8101           0 :                                              op->EnergyMeters(Meter).DYRptNumChr,
    8102           0 :                                              op->EnergyMeters(Meter).Name,
    8103           0 :                                              op->EnergyMeters(Meter).Units,
    8104             :                                              false,
    8105             :                                              false);
    8106             :                 }
    8107        1150 :             } else if (ReportFreq == ReportingFrequency::Monthly) {
    8108        1131 :                 if (op->EnergyMeters(Meter).RptMN) {
    8109          44 :                     op->EnergyMeters(Meter).RptMN = true;
    8110          44 :                     op->TrackingMonthlyVariables = true;
    8111             :                 } else {
    8112        1087 :                     op->EnergyMeters(Meter).RptMN = true;
    8113        1087 :                     op->TrackingMonthlyVariables = true;
    8114        4348 :                     WriteMeterDictionaryItem(state,
    8115             :                                              ReportFreq,
    8116             :                                              StoreType::Summed,
    8117        1087 :                                              op->EnergyMeters(Meter).MNRptNum,
    8118             :                                              indexGroupKey,
    8119             :                                              indexGroup,
    8120        1087 :                                              op->EnergyMeters(Meter).MNRptNumChr,
    8121        1087 :                                              op->EnergyMeters(Meter).Name,
    8122        1087 :                                              op->EnergyMeters(Meter).Units,
    8123             :                                              false,
    8124             :                                              false);
    8125             :                 }
    8126          19 :             } else if (ReportFreq == ReportingFrequency::Yearly) {
    8127          19 :                 if (op->EnergyMeters(Meter).RptYR) {
    8128          18 :                     op->EnergyMeters(Meter).RptYR = true;
    8129          18 :                     op->TrackingYearlyVariables = true;
    8130             :                 } else {
    8131           1 :                     op->EnergyMeters(Meter).RptYR = true;
    8132           1 :                     op->TrackingMonthlyVariables = true;
    8133           4 :                     WriteMeterDictionaryItem(state,
    8134             :                                              ReportFreq,
    8135             :                                              StoreType::Summed,
    8136           1 :                                              op->EnergyMeters(Meter).YRRptNum,
    8137             :                                              indexGroupKey,
    8138             :                                              indexGroup,
    8139           1 :                                              op->EnergyMeters(Meter).YRRptNumChr,
    8140           1 :                                              op->EnergyMeters(Meter).Name,
    8141           1 :                                              op->EnergyMeters(Meter).Units,
    8142             :                                              false,
    8143             :                                              false);
    8144             :                 }
    8145           0 :             } else if (ReportFreq == ReportingFrequency::Simulation) {
    8146           0 :                 if (op->EnergyMeters(Meter).RptSM) {
    8147           0 :                     op->EnergyMeters(Meter).RptSM = true;
    8148           0 :                     op->TrackingRunPeriodVariables = true;
    8149             :                 } else {
    8150           0 :                     op->EnergyMeters(Meter).RptSM = true;
    8151           0 :                     op->TrackingRunPeriodVariables = true;
    8152           0 :                     WriteMeterDictionaryItem(state,
    8153             :                                              ReportFreq,
    8154             :                                              StoreType::Summed,
    8155           0 :                                              op->EnergyMeters(Meter).SMRptNum,
    8156             :                                              indexGroupKey,
    8157             :                                              indexGroup,
    8158           0 :                                              op->EnergyMeters(Meter).SMRptNumChr,
    8159           0 :                                              op->EnergyMeters(Meter).Name,
    8160           0 :                                              op->EnergyMeters(Meter).Units,
    8161             :                                              false,
    8162             :                                              false);
    8163             :                 }
    8164             :             } else {
    8165             :             }
    8166             :         }
    8167             :     }
    8168          60 : }
    8169             : 
    8170         769 : void ProduceRDDMDD(EnergyPlusData &state)
    8171             : {
    8172             : 
    8173             :     // SUBROUTINE INFORMATION:
    8174             :     //       AUTHOR         Linda Lawrie
    8175             :     //       DATE WRITTEN   March 2009
    8176             :     //       MODIFIED       na
    8177             :     //       RE-ENGINEERED  na
    8178             : 
    8179             :     // PURPOSE OF THIS SUBROUTINE:
    8180             :     // provide a single call for writing out the Report Data Dictionary and Meter Data Dictionary.
    8181             : 
    8182             :     // Using/Aliasing
    8183             :     using namespace OutputProcessor;
    8184             :     using General::ScanForReports;
    8185             :     using SortAndStringUtilities::SetupAndSort;
    8186             : 
    8187             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    8188        1538 :     std::string VarOption1;
    8189        1538 :     std::string VarOption2;
    8190             :     bool DoReport;
    8191             :     int Item;
    8192             :     bool SortByName;
    8193             :     int ItemPtr;
    8194             : 
    8195             :     struct VariableTypes
    8196             :     {
    8197             :         // Members
    8198             :         int RealIntegerType; // Real= 1, Integer=2
    8199             :         int VarPtr;          // pointer to real/integer VariableTypes structures
    8200             :         int TimeStepType;
    8201             :         int StoreType;
    8202             :         std::string UnitsString;
    8203             : 
    8204             :         // Default Constructor
    8205             :         VariableTypes() : RealIntegerType(0), VarPtr(0), TimeStepType(0), StoreType(0)
    8206             :         {
    8207             :         }
    8208             :     };
    8209             : 
    8210         769 :     auto &op(state.dataOutputProcessor);
    8211             : 
    8212             :     //  See if Report Variables should be turned on
    8213         769 :     SortByName = false;
    8214         769 :     ScanForReports(state, "VariableDictionary", DoReport, _, VarOption1, VarOption2);
    8215             :     //  IF (.not. DoReport) RETURN
    8216             : 
    8217         769 :     if (DoReport) {
    8218         755 :         op->ProduceReportVDD = ReportVDD::Yes;
    8219         755 :         if (VarOption1 == std::string("IDF")) {
    8220         248 :             op->ProduceReportVDD = ReportVDD::IDF;
    8221             :         }
    8222         755 :         if (!VarOption2.empty()) {
    8223          67 :             if (UtilityRoutines::SameString(VarOption2, "Name") || UtilityRoutines::SameString(VarOption2, "AscendingName")) {
    8224           3 :                 SortByName = true;
    8225             :             }
    8226             :         }
    8227             :     }
    8228             : 
    8229         769 :     state.files.rdd.ensure_open(state, "ProduceRDDMDD", state.files.outputControl.rdd);
    8230         769 :     state.files.mdd.ensure_open(state, "ProduceRDDMDD", state.files.outputControl.mdd);
    8231         769 :     if (op->ProduceReportVDD == ReportVDD::Yes) {
    8232         507 :         print(state.files.rdd, "Program Version,{},{}{}", state.dataStrGlobals->VerStringVar, state.dataStrGlobals->IDDVerString, '\n');
    8233         507 :         print(state.files.rdd, "Var Type (reported time step),Var Report Type,Variable Name [Units]{}", '\n');
    8234             : 
    8235         507 :         print(state.files.mdd, "Program Version,{},{}{}", state.dataStrGlobals->VerStringVar, state.dataStrGlobals->IDDVerString, '\n');
    8236         507 :         print(state.files.mdd, "Var Type (reported time step),Var Report Type,Variable Name [Units]{}", '\n');
    8237         262 :     } else if (op->ProduceReportVDD == ReportVDD::IDF) {
    8238         248 :         print(state.files.rdd, "! Program Version,{},{}{}", state.dataStrGlobals->VerStringVar, state.dataStrGlobals->IDDVerString, '\n');
    8239         248 :         print(state.files.rdd, "! Output:Variable Objects (applicable to this run){}", '\n');
    8240             : 
    8241         248 :         print(state.files.mdd, "! Program Version,{},{}{}", state.dataStrGlobals->VerStringVar, state.dataStrGlobals->IDDVerString, '\n');
    8242         248 :         print(state.files.mdd, "! Output:Meter Objects (applicable to this run){}", '\n');
    8243             :     }
    8244             : 
    8245        1538 :     Array1D_string VariableNames(op->NumVariablesForOutput);
    8246      446578 :     for (int i = 1; i <= op->NumVariablesForOutput; ++i)
    8247      445809 :         VariableNames(i) = op->DDVariableTypes(i).VarNameOnly;
    8248        1538 :     Array1D_int iVariableNames(op->NumVariablesForOutput);
    8249             : 
    8250         769 :     if (SortByName) {
    8251           3 :         SetupAndSort(VariableNames, iVariableNames);
    8252             :     } else {
    8253      445371 :         for (Item = 1; Item <= op->NumVariablesForOutput; ++Item) {
    8254      444605 :             iVariableNames(Item) = Item;
    8255             :         }
    8256             :     }
    8257             : 
    8258      446578 :     for (Item = 1; Item <= op->NumVariablesForOutput; ++Item) {
    8259      445809 :         if (op->ProduceReportVDD == ReportVDD::Yes) {
    8260      289235 :             ItemPtr = iVariableNames(Item);
    8261      289235 :             if (!op->DDVariableTypes(ItemPtr).ReportedOnDDFile) {
    8262     1156924 :                 print(state.files.rdd,
    8263             :                       "{},{},{}{}{}",
    8264      578462 :                       StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType),
    8265      578462 :                       standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType),
    8266             :                       VariableNames(Item),
    8267      578462 :                       unitStringFromDDitem(state, ItemPtr),
    8268      289231 :                       '\n');
    8269     1156924 :                 state.dataResultsFramework->resultsFramework->RDD.push_back(StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType) + "," +
    8270     1156924 :                                                                             standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType) + "," +
    8271     1156924 :                                                                             VariableNames(Item) + unitStringFromDDitem(state, ItemPtr));
    8272      289231 :                 op->DDVariableTypes(ItemPtr).ReportedOnDDFile = true;
    8273      289239 :                 while (op->DDVariableTypes(ItemPtr).Next != 0) {
    8274           4 :                     if (SortByName) {
    8275           0 :                         ++ItemPtr;
    8276             :                     } else {
    8277           4 :                         ItemPtr = op->DDVariableTypes(ItemPtr).Next;
    8278             :                     }
    8279          16 :                     print(state.files.rdd,
    8280             :                           "{},{},{}{}{}",
    8281           8 :                           StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType),
    8282           8 :                           standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType),
    8283             :                           VariableNames(Item),
    8284           8 :                           unitStringFromDDitem(state, ItemPtr),
    8285           4 :                           '\n');
    8286          16 :                     state.dataResultsFramework->resultsFramework->RDD.push_back(StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType) +
    8287           8 :                                                                                 "," +
    8288          16 :                                                                                 standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType) +
    8289          16 :                                                                                 "," + VariableNames(Item) + unitStringFromDDitem(state, ItemPtr));
    8290           4 :                     op->DDVariableTypes(ItemPtr).ReportedOnDDFile = true;
    8291             :                 }
    8292             :             }
    8293      156574 :         } else if (op->ProduceReportVDD == ReportVDD::IDF) {
    8294      148380 :             ItemPtr = iVariableNames(Item);
    8295      148380 :             if (!op->DDVariableTypes(ItemPtr).ReportedOnDDFile) {
    8296      593516 :                 print(state.files.rdd,
    8297             :                       "Output:Variable,*,{},hourly; !- {} {}{}{}",
    8298             :                       VariableNames(Item),
    8299      296758 :                       StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType),
    8300      296758 :                       standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType),
    8301      296758 :                       unitStringFromDDitem(state, ItemPtr),
    8302      148379 :                       '\n');
    8303      593516 :                 state.dataResultsFramework->resultsFramework->RDD.push_back(StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType) + "," +
    8304      593516 :                                                                             standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType) + "," +
    8305      593516 :                                                                             VariableNames(Item) + unitStringFromDDitem(state, ItemPtr));
    8306      148379 :                 op->DDVariableTypes(ItemPtr).ReportedOnDDFile = true;
    8307      148381 :                 while (op->DDVariableTypes(ItemPtr).Next != 0) {
    8308           1 :                     if (SortByName) {
    8309           0 :                         ++ItemPtr;
    8310             :                     } else {
    8311           1 :                         ItemPtr = op->DDVariableTypes(ItemPtr).Next;
    8312             :                     }
    8313           4 :                     print(state.files.rdd,
    8314             :                           "Output:Variable,*,{},hourly; !- {} {}{}{}",
    8315             :                           VariableNames(Item),
    8316           2 :                           StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType),
    8317           2 :                           standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType),
    8318           2 :                           unitStringFromDDitem(state, ItemPtr),
    8319           1 :                           '\n');
    8320           4 :                     state.dataResultsFramework->resultsFramework->RDD.push_back(StandardTimeStepTypeKey(op->DDVariableTypes(ItemPtr).timeStepType) +
    8321           2 :                                                                                 "," +
    8322           4 :                                                                                 standardVariableTypeKey(op->DDVariableTypes(ItemPtr).storeType) +
    8323           4 :                                                                                 "," + VariableNames(Item) + unitStringFromDDitem(state, ItemPtr));
    8324           1 :                     op->DDVariableTypes(ItemPtr).ReportedOnDDFile = true;
    8325             :                 }
    8326             :             }
    8327             :         }
    8328             :     }
    8329         769 :     state.files.rdd.close();
    8330             : 
    8331             :     //  Now EnergyMeter variables
    8332         769 :     VariableNames.allocate(op->NumEnergyMeters);
    8333         769 :     iVariableNames.allocate(op->NumEnergyMeters);
    8334         769 :     if (SortByName) {
    8335         202 :         for (Item = 1; Item <= op->NumEnergyMeters; ++Item) {
    8336         199 :             VariableNames(Item) = op->EnergyMeters(Item).Name;
    8337             :         }
    8338           3 :         SetupAndSort(VariableNames, iVariableNames);
    8339             :     } else {
    8340       93456 :         for (Item = 1; Item <= op->NumEnergyMeters; ++Item) {
    8341       92690 :             VariableNames(Item) = op->EnergyMeters(Item).Name;
    8342       92690 :             iVariableNames(Item) = Item;
    8343             :         }
    8344             :     }
    8345             : 
    8346       93658 :     for (Item = 1; Item <= op->NumEnergyMeters; ++Item) {
    8347       92889 :         ItemPtr = iVariableNames(Item);
    8348       92889 :         if (op->ProduceReportVDD == ReportVDD::Yes) {
    8349      185544 :             print(state.files.mdd,
    8350             :                   "Zone,Meter,{}{}{}",
    8351       46386 :                   op->EnergyMeters(ItemPtr).Name,
    8352       92772 :                   unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units),
    8353       46386 :                   '\n');
    8354       92772 :             state.dataResultsFramework->resultsFramework->MDD.push_back("Zone,Meter," + op->EnergyMeters(ItemPtr).Name +
    8355       92772 :                                                                         unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units));
    8356       46503 :         } else if (op->ProduceReportVDD == ReportVDD::IDF) {
    8357      179840 :             print(state.files.mdd,
    8358             :                   "Output:Meter,{},hourly; !-{}{}",
    8359       44960 :                   op->EnergyMeters(ItemPtr).Name,
    8360       89920 :                   unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units),
    8361       44960 :                   '\n');
    8362       89920 :             state.dataResultsFramework->resultsFramework->MDD.push_back("Output:Meter," + op->EnergyMeters(ItemPtr).Name +
    8363       89920 :                                                                         unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units));
    8364      179840 :             print(state.files.mdd,
    8365             :                   "Output:Meter:Cumulative,{},hourly; !-{}{}",
    8366       44960 :                   op->EnergyMeters(ItemPtr).Name,
    8367       89920 :                   unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units),
    8368       44960 :                   '\n');
    8369       89920 :             state.dataResultsFramework->resultsFramework->MDD.push_back("Output:Meter:Cumulative," + op->EnergyMeters(ItemPtr).Name +
    8370       89920 :                                                                         unitEnumToStringBrackets(op->EnergyMeters(ItemPtr).Units));
    8371             :         }
    8372             :     }
    8373         769 :     state.files.mdd.close();
    8374         769 : }
    8375             : 
    8376     6084576 : void AddToOutputVariableList(EnergyPlusData &state,
    8377             :                              std::string_view const VarName, // Variable Name
    8378             :                              OutputProcessor::TimeStepType const TimeStepType,
    8379             :                              OutputProcessor::StoreType const StateType,
    8380             :                              OutputProcessor::VariableType const VariableType,
    8381             :                              OutputProcessor::Unit const unitsForVar,
    8382             :                              Optional_string_const customUnitName // the custom name for the units from EMS definition of units
    8383             : )
    8384             : {
    8385             : 
    8386             :     // SUBROUTINE INFORMATION:
    8387             :     //       AUTHOR         Linda Lawrie
    8388             :     //       DATE WRITTEN   August 2010
    8389             :     //       MODIFIED       na
    8390             :     //       RE-ENGINEERED  na
    8391             : 
    8392             :     // PURPOSE OF THIS SUBROUTINE:
    8393             :     // This routine maintains a unique list of Output Variables for the
    8394             :     // Variable Dictionary output.
    8395             : 
    8396             :     // METHODOLOGY EMPLOYED:
    8397             :     // na
    8398             : 
    8399             :     // REFERENCES:
    8400             :     // na
    8401             : 
    8402             :     // Using/Aliasing
    8403             :     using namespace OutputProcessor;
    8404             : 
    8405             :     // Locals
    8406             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    8407             : 
    8408             :     // SUBROUTINE PARAMETER DEFINITIONS:
    8409             :     // na
    8410             : 
    8411             :     // INTERFACE BLOCK SPECIFICATIONS:
    8412             :     // na
    8413             : 
    8414             :     // DERIVED TYPE DEFINITIONS:
    8415             :     // na
    8416             : 
    8417             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    8418     6084576 :     auto &op(state.dataOutputProcessor);
    8419             : 
    8420     6084576 :     int dup = 0; // for duplicate variable name
    8421     6084576 :     if (op->NumVariablesForOutput > 0) {
    8422     6083805 :         dup = UtilityRoutines::FindItemInList(VarName, op->DDVariableTypes, &VariableTypeForDDOutput::VarNameOnly, op->NumVariablesForOutput);
    8423             :     } else {
    8424         771 :         op->DDVariableTypes.allocate(LVarAllocInc);
    8425         771 :         op->MaxVariablesForOutput = LVarAllocInc;
    8426             :     }
    8427     6084576 :     if (dup == 0) {
    8428      446765 :         ++op->NumVariablesForOutput;
    8429      446765 :         if (op->NumVariablesForOutput > op->MaxVariablesForOutput) {
    8430           1 :             op->DDVariableTypes.redimension(op->MaxVariablesForOutput += LVarAllocInc);
    8431             :         }
    8432      446765 :         op->DDVariableTypes(op->NumVariablesForOutput).timeStepType = TimeStepType;
    8433      446765 :         op->DDVariableTypes(op->NumVariablesForOutput).storeType = StateType;
    8434      446765 :         op->DDVariableTypes(op->NumVariablesForOutput).variableType = VariableType;
    8435      446765 :         op->DDVariableTypes(op->NumVariablesForOutput).VarNameOnly = VarName;
    8436      446765 :         op->DDVariableTypes(op->NumVariablesForOutput).units = unitsForVar;
    8437      446765 :         if (present(customUnitName) && unitsForVar == OutputProcessor::Unit::customEMS) {
    8438          10 :             op->DDVariableTypes(op->NumVariablesForOutput).unitNameCustomEMS = customUnitName;
    8439             :         }
    8440     5637811 :     } else if (unitsForVar != op->DDVariableTypes(dup).units) { // not the same as first units
    8441           6 :         int dup2 = 0;                                           // for duplicate variable name
    8442           8 :         while (op->DDVariableTypes(dup).Next != 0) {
    8443           3 :             if (unitsForVar != op->DDVariableTypes(op->DDVariableTypes(dup).Next).units) {
    8444           1 :                 dup = op->DDVariableTypes(dup).Next;
    8445           1 :                 continue;
    8446             :             }
    8447           1 :             dup2 = op->DDVariableTypes(dup).Next;
    8448           1 :             break;
    8449             :         }
    8450           6 :         if (dup2 == 0) {
    8451           5 :             ++op->NumVariablesForOutput;
    8452           5 :             if (op->NumVariablesForOutput > op->MaxVariablesForOutput) {
    8453           0 :                 op->DDVariableTypes.redimension(op->MaxVariablesForOutput += LVarAllocInc);
    8454             :             }
    8455           5 :             op->DDVariableTypes(op->NumVariablesForOutput).timeStepType = TimeStepType;
    8456           5 :             op->DDVariableTypes(op->NumVariablesForOutput).storeType = StateType;
    8457           5 :             op->DDVariableTypes(op->NumVariablesForOutput).variableType = VariableType;
    8458           5 :             op->DDVariableTypes(op->NumVariablesForOutput).VarNameOnly = VarName;
    8459           5 :             op->DDVariableTypes(op->NumVariablesForOutput).units = unitsForVar;
    8460           5 :             if (present(customUnitName) && unitsForVar == OutputProcessor::Unit::customEMS) {
    8461           0 :                 op->DDVariableTypes(op->NumVariablesForOutput).unitNameCustomEMS = customUnitName;
    8462             :             }
    8463           5 :             op->DDVariableTypes(dup).Next = op->NumVariablesForOutput;
    8464             :         }
    8465             :     }
    8466     6084576 : }
    8467             : 
    8468         771 : int initErrorFile(EnergyPlusData &state)
    8469             : {
    8470         771 :     state.files.err_stream = std::make_unique<std::ofstream>(state.files.outputErrFilePath);
    8471         771 :     if (state.files.err_stream->bad()) {
    8472           0 :         DisplayString(state, "ERROR: Could not open file " + state.files.outputErrFilePath.string() + " for output (write).");
    8473           0 :         return EXIT_FAILURE;
    8474             :     }
    8475         771 :     return EXIT_SUCCESS;
    8476             : }
    8477             : 
    8478        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13