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 : #include <cmath>
49 :
50 : #include <ObjexxFCL/ArrayS.functions.hh>
51 : #include <ObjexxFCL/time.hh>
52 :
53 : #include <EnergyPlus/Construction.hh>
54 : #include <EnergyPlus/Data/EnergyPlusData.hh>
55 : #include <EnergyPlus/DataEnvironment.hh>
56 : #include <EnergyPlus/DataHVACGlobals.hh>
57 : #include <EnergyPlus/DataRuntimeLanguage.hh>
58 : #include <EnergyPlus/HeatBalFiniteDiffManager.hh>
59 : #include <EnergyPlus/OutputProcessor.hh>
60 : #include <EnergyPlus/PluginManager.hh>
61 : #include <EnergyPlus/RuntimeLanguageProcessor.hh>
62 : #include <EnergyPlus/UtilityRoutines.hh>
63 : #include <EnergyPlus/WeatherManager.hh>
64 : #include <EnergyPlus/api/datatransfer.h>
65 : #include <EnergyPlus/api/runtime.h>
66 :
67 0 : char *listAllAPIDataCSV(EnergyPlusState state)
68 : {
69 0 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
70 0 : std::string output = "**ACTUATORS**\n";
71 0 : for (auto const &availActuator : thisState->dataRuntimeLang->EMSActuatorAvailable) {
72 0 : if (availActuator.ComponentTypeName.empty() && availActuator.UniqueIDName.empty() && availActuator.ControlTypeName.empty()) {
73 0 : break;
74 : }
75 0 : output.append("Actuator,");
76 0 : output.append(availActuator.ComponentTypeName).append(",");
77 0 : output.append(availActuator.ControlTypeName).append(",");
78 0 : output.append(availActuator.UniqueIDName).append(";\n");
79 : }
80 0 : output.append("**INTERNAL_VARIABLES**\n");
81 0 : for (auto const &availVariable : thisState->dataRuntimeLang->EMSInternalVarsAvailable) {
82 0 : if (availVariable.DataTypeName.empty() && availVariable.UniqueIDName.empty()) {
83 0 : break;
84 : }
85 0 : output.append("InternalVariable,");
86 0 : output.append(availVariable.DataTypeName).append(",");
87 0 : output.append(availVariable.UniqueIDName).append("\n");
88 : }
89 0 : output.append("**PLUGIN_GLOBAL_VARIABLES**\n");
90 0 : for (auto const &gVarName : thisState->dataPluginManager->globalVariableNames) {
91 0 : output.append("PluginGlobalVariable,");
92 0 : output.append(gVarName).append("\n");
93 : }
94 0 : output.append("**TRENDS**\n");
95 0 : for (auto const &trend : thisState->dataPluginManager->trends) {
96 0 : output.append("PluginTrendVariable,");
97 0 : output.append(trend.name).append("\n");
98 : }
99 0 : output.append("**METERS**\n");
100 0 : for (auto const &meter : thisState->dataOutputProcessor->EnergyMeters) {
101 0 : if (meter.Name.empty()) {
102 0 : break;
103 : }
104 0 : output.append("OutputMeter,");
105 0 : output.append(meter.Name).append("\n");
106 : }
107 0 : output.append("**VARIABLES**\n");
108 0 : for (auto const &variable : thisState->dataOutputProcessor->RVariableTypes) {
109 0 : if (variable.VarNameOnly.empty() && variable.KeyNameOnlyUC.empty()) {
110 0 : break;
111 : }
112 0 : output.append("OutputVariable,");
113 0 : output.append(variable.VarNameOnly).append(",");
114 0 : output.append(variable.KeyNameOnlyUC).append("\n");
115 : }
116 : // note that we cannot just return a c_str to the local string, as the string will be destructed upon leaving
117 : // this function, and undefined behavior will occur.
118 : // instead make a deep copy, and the user must manage the new char * pointer
119 : // strcpy copies including the null-terminator, strlen doesn't include it
120 0 : char *p = new char[std::strlen(output.c_str()) + 1];
121 0 : std::strcpy(p, output.c_str());
122 0 : return p;
123 : }
124 :
125 354836 : int apiDataFullyReady(EnergyPlusState state)
126 : {
127 354836 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
128 354836 : if (thisState->dataPluginManager->fullyReady) {
129 346844 : return 0;
130 : }
131 7992 : return 1;
132 : }
133 :
134 0 : int apiErrorFlag(EnergyPlusState state)
135 : {
136 0 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
137 0 : if (thisState->dataPluginManager->apiErrorFlag) {
138 0 : return 1;
139 : } else {
140 0 : return 0;
141 : }
142 : }
143 :
144 0 : void resetErrorFlag(EnergyPlusState state)
145 : {
146 0 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
147 0 : thisState->dataPluginManager->apiErrorFlag = false;
148 0 : }
149 :
150 13 : int getNumNodesInCondFDSurfaceLayer(EnergyPlusState state, const char *surfName, const char *matName)
151 : {
152 13 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
153 26 : auto UCsurfName = EnergyPlus::UtilityRoutines::MakeUPPERCase(surfName);
154 26 : auto UCmatName = EnergyPlus::UtilityRoutines::MakeUPPERCase(matName);
155 26 : return EnergyPlus::HeatBalFiniteDiffManager::numNodesInMaterialLayer(*thisState, UCsurfName, UCmatName);
156 : }
157 :
158 0 : void requestVariable(EnergyPlusState state, const char *type, const char *key)
159 : {
160 : // allow specifying a request for an output variable, so that E+ does not have to keep all of them in memory
161 : // should be called before energyplus is run!
162 : // note that the variable request array is cleared during clear_state, so if you run multiple E+ runs, these must be requested again each time.
163 0 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
164 0 : EnergyPlus::OutputProcessor::APIOutputVariableRequest request;
165 0 : request.varName = type;
166 0 : request.varKey = key;
167 0 : thisState->dataOutputProcessor->apiVarRequests.push_back(request);
168 0 : }
169 :
170 123 : int getVariableHandle(EnergyPlusState state, const char *type, const char *key)
171 : {
172 : // Variables are accessed through a single integer ID, but there are multiple internal types: real and integer.
173 : // I am going to make the integer handle span all both types, by carefully defining the handle.
174 : // basically, the handles are contiguous, with:
175 : // - index 1 being the first real variable handle
176 : // - index N being the highest real variable handle
177 : // - index N+1 being the first integer variable handle
178 : // - index N+M being the highest integer variable handle
179 : // In this function, it is as simple as looping over both types and continuing to increment
180 : // the handle carefully. In the getValue function it is just a matter of checking array sizes.
181 123 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
182 246 : std::string const typeUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(type);
183 246 : std::string const keyUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(key);
184 123 : int handle = -1; // initialize to -1 as a flag
185 123 : if (thisState->dataOutputProcessor->RVariableTypes.allocated()) {
186 123 : handle = 0; // initialize to 0 to get a 1 based Array1D index
187 39210 : for (int i = 1; i <= thisState->dataOutputProcessor->NumOfRVariable; i++) {
188 39205 : auto &availOutputVar = thisState->dataOutputProcessor->RVariableTypes(i);
189 39205 : handle++;
190 39205 : if (typeUC == availOutputVar.VarNameOnlyUC && keyUC == availOutputVar.KeyNameOnlyUC) {
191 118 : return handle;
192 : }
193 : }
194 : }
195 5 : if (thisState->dataOutputProcessor->IVariableTypes.allocated()) {
196 : // now, if real variables *were* searched, we need to pick up the handle where it left off, otherwise initialize it to zero
197 5 : if (handle == -1) {
198 : // real variables were not searched, init to zero
199 0 : handle = 0;
200 : } else {
201 : // real variables where searched, let it just continue where it left off
202 : }
203 5 : for (int i = 1; i <= thisState->dataOutputProcessor->NumOfIVariable; i++) {
204 0 : auto &availOutputVar = thisState->dataOutputProcessor->IVariableTypes(i);
205 0 : handle++;
206 0 : if (typeUC == availOutputVar.VarNameOnlyUC && keyUC == availOutputVar.KeyNameOnlyUC) {
207 0 : return handle;
208 : }
209 : }
210 : }
211 5 : return -1; // return -1 if it wasn't found
212 : }
213 :
214 740179 : Real64 getVariableValue(EnergyPlusState state, const int handle)
215 : {
216 : // this function works in conjunction with the plan set up in getVariableHandle
217 : // basically, the handles are contiguous, with:
218 : // - index 1 being the first real variable handle
219 : // - index N being the highest real variable handle
220 : // - index N+1 being the first integer variable handle
221 : // - index N+M being the highest integer variable handle
222 : // note that this function will return -1 if it cannot
223 740179 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
224 740179 : if (handle > 0 && handle <= thisState->dataOutputProcessor->NumOfRVariable) {
225 740179 : auto &thisOutputVar = thisState->dataOutputProcessor->RVariableTypes(handle);
226 740179 : return *thisOutputVar.VarPtr.Which;
227 0 : } else if (handle > thisState->dataOutputProcessor->NumOfRVariable &&
228 0 : handle <= thisState->dataOutputProcessor->NumOfRVariable + thisState->dataOutputProcessor->NumOfIVariable) {
229 0 : int thisHandle = handle - thisState->dataOutputProcessor->NumOfRVariable;
230 0 : auto &thisOutputVar = thisState->dataOutputProcessor->IVariableTypes(thisHandle);
231 0 : return (Real64)*thisOutputVar.VarPtr.Which;
232 : } else {
233 0 : if (thisState->dataGlobal->errorCallback) {
234 0 : std::cout << "ERROR: Variable handle out of range in getVariableValue, returning zero but caller should take note and likely abort."
235 0 : << std::endl;
236 : } else {
237 : // must be running from python plugin, need to fatal out once the plugin is done
238 : // throw an error, set the fatal flag, and then return zero
239 0 : EnergyPlus::ShowSevereError(*thisState, fmt::format("Data Exchange API: Index error in getVariableValue; received handle: {}", handle));
240 0 : EnergyPlus::ShowContinueError(
241 : *thisState, "The getVariableValue function will return 0 for now to allow the plugin to finish, then EnergyPlus will abort");
242 : }
243 0 : thisState->dataPluginManager->apiErrorFlag = true;
244 0 : return 0;
245 : }
246 : }
247 :
248 0 : int getMeterHandle(EnergyPlusState state, const char *meterName)
249 : {
250 0 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
251 0 : std::string const meterNameUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(meterName);
252 0 : auto i = EnergyPlus::GetMeterIndex(*thisState, meterNameUC);
253 0 : if (i == 0) {
254 : // inside E+, zero is meaningful, but through the API, I want to use negative one as a signal of a bad lookup
255 0 : return -1;
256 : } else {
257 0 : return i;
258 : }
259 : }
260 :
261 0 : Real64 getMeterValue(EnergyPlusState state, int handle)
262 : {
263 0 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
264 0 : if (handle >= 1 && handle <= (int)thisState->dataOutputProcessor->EnergyMeters.size()) {
265 0 : return EnergyPlus::GetCurrentMeterValue(*thisState, handle);
266 : } else {
267 0 : if (thisState->dataGlobal->errorCallback) {
268 0 : std::cout << "ERROR: Meter handle out of range in getMeterValue, returning zero but caller should take note and likely abort."
269 0 : << std::endl;
270 : } else {
271 : // must be running from python plugin, need to fatal out once the plugin is done
272 : // throw an error, set the fatal flag, and then return zero
273 0 : EnergyPlus::ShowSevereError(*thisState, fmt::format("Data Exchange API: Index error in getMeterValue; received handle: {}", handle));
274 0 : EnergyPlus::ShowContinueError(
275 : *thisState, "The getMeterValue function will return 0 for now to allow the plugin to finish, then EnergyPlus will abort");
276 : }
277 0 : thisState->dataPluginManager->apiErrorFlag = true;
278 0 : return 0;
279 : }
280 : }
281 :
282 155 : int getActuatorHandle(EnergyPlusState state, const char *componentType, const char *controlType, const char *uniqueKey)
283 : {
284 155 : int handle = 0;
285 310 : std::string const typeUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(componentType);
286 310 : std::string const keyUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(uniqueKey);
287 310 : std::string const controlUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(controlType);
288 155 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
289 122565 : for (int ActuatorLoop = 1; ActuatorLoop <= thisState->dataRuntimeLang->numEMSActuatorsAvailable; ++ActuatorLoop) {
290 122562 : auto &availActuator = thisState->dataRuntimeLang->EMSActuatorAvailable(ActuatorLoop);
291 122562 : handle++;
292 244972 : std::string const actuatorTypeUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(availActuator.ComponentTypeName);
293 244972 : std::string const actuatorIDUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(availActuator.UniqueIDName);
294 244972 : std::string const actuatorControlUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(availActuator.ControlTypeName);
295 122562 : if (typeUC == actuatorTypeUC && keyUC == actuatorIDUC && controlUC == actuatorControlUC) {
296 :
297 152 : if (availActuator.handleCount > 0) {
298 : // If the handle is already used by an IDF EnergyManagementSystem:Actuator, we should warn the user
299 5 : bool foundActuator = false;
300 143 : for (auto const &usedActuator : thisState->dataRuntimeLang->EMSActuatorUsed) {
301 138 : if (usedActuator.ActuatorVariableNum == handle) {
302 0 : EnergyPlus::ShowWarningError(
303 : *thisState,
304 0 : "Data Exchange API: An EnergyManagementSystem:Actuator seems to be already defined in the EnergyPlus File and named '" +
305 0 : usedActuator.Name + "'.");
306 0 : EnergyPlus::ShowContinueError(
307 0 : *thisState, "Occurred for componentType='" + typeUC + "', controlType='" + controlUC + "', uniqueKey='" + keyUC + "'.");
308 0 : EnergyPlus::ShowContinueError(*thisState,
309 0 : fmt::format("The getActuatorHandle function will still return the handle (= {}) but caller "
310 : "should take note that there is a risk of overwritting.",
311 : handle));
312 0 : foundActuator = true;
313 0 : break;
314 : }
315 : }
316 5 : if (!foundActuator) {
317 5 : EnergyPlus::ShowWarningError(*thisState,
318 : "Data Exchange API: You seem to already have tried to get an Actuator Handle on this one.");
319 15 : EnergyPlus::ShowContinueError(
320 10 : *thisState, "Occurred for componentType='" + typeUC + "', controlType='" + controlUC + "', uniqueKey='" + keyUC + "'.");
321 15 : EnergyPlus::ShowContinueError(*thisState,
322 5 : fmt::format("The getActuatorHandle function will still return the handle (= {}) but caller should "
323 : "take note that there is a risk of overwritting.",
324 : handle));
325 : }
326 : }
327 152 : ++availActuator.handleCount;
328 :
329 152 : return handle;
330 : }
331 : }
332 3 : return -1;
333 : }
334 :
335 134102 : void resetActuator(EnergyPlusState state, int handle)
336 : {
337 : // resets the actuator so that E+ will use the internally calculated value again
338 134102 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
339 134102 : if (handle >= 1 && handle <= thisState->dataRuntimeLang->numEMSActuatorsAvailable) {
340 134102 : auto &theActuator(thisState->dataRuntimeLang->EMSActuatorAvailable(handle));
341 134102 : *theActuator.Actuated = false;
342 : } else {
343 0 : if (thisState->dataGlobal->errorCallback) {
344 0 : std::cout << "ERROR: Actuator handle out of range in resetActuator, returning but caller should take note and likely abort." << std::endl;
345 : } else {
346 : // must be running from python plugin, need to fatal out once the plugin is done
347 : // throw an error, set the fatal flag, and then return
348 0 : EnergyPlus::ShowSevereError(*thisState, fmt::format("Data Exchange API: index error in resetActuator; received handle: {}", handle));
349 0 : EnergyPlus::ShowContinueError(*thisState,
350 : "The resetActuator function will return to allow the plugin to finish, then EnergyPlus will abort");
351 : }
352 0 : thisState->dataPluginManager->apiErrorFlag = true;
353 : }
354 134102 : }
355 :
356 899253 : void setActuatorValue(EnergyPlusState state, const int handle, const Real64 value)
357 : {
358 899253 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
359 899253 : if (handle >= 1 && handle <= thisState->dataRuntimeLang->numEMSActuatorsAvailable) {
360 899253 : auto &theActuator(thisState->dataRuntimeLang->EMSActuatorAvailable(handle));
361 899253 : if (theActuator.RealValue) {
362 850219 : *theActuator.RealValue = value;
363 49034 : } else if (theActuator.IntValue) {
364 49034 : *theActuator.IntValue = (int)std::lround(value);
365 : } else {
366 : // follow protocol from EMS manager, where 1.0 is true, 0.0 is false, and anything else is also false
367 0 : *theActuator.LogValue = value > 0.99999 && value < 1.00001; // allow small tolerance while passing between languages and types
368 : }
369 899253 : *theActuator.Actuated = true;
370 : } else {
371 0 : if (thisState->dataGlobal->errorCallback) {
372 0 : std::cout << "ERROR: Actuator handle out of range in setActuatorValue, returning but caller should take note and likely abort."
373 0 : << std::endl;
374 : } else {
375 : // must be running from python plugin, need to fatal out once the plugin is done
376 : // throw an error, set the fatal flag, and then return
377 0 : EnergyPlus::ShowSevereError(*thisState, fmt::format("Data Exchange API: index error in setActuatorValue; received handle: {}", handle));
378 0 : EnergyPlus::ShowContinueError(*thisState,
379 : "The setActuatorValue function will return to allow the plugin to finish, then EnergyPlus will abort");
380 : }
381 0 : thisState->dataPluginManager->apiErrorFlag = true;
382 : }
383 899253 : }
384 :
385 42474 : Real64 getActuatorValue(EnergyPlusState state, const int handle)
386 : {
387 42474 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
388 42474 : if (handle >= 1 && handle <= thisState->dataRuntimeLang->numEMSActuatorsAvailable) {
389 42474 : auto &theActuator(thisState->dataRuntimeLang->EMSActuatorAvailable(handle));
390 42474 : if (theActuator.RealValue) {
391 42474 : return *theActuator.RealValue;
392 0 : } else if (theActuator.IntValue) {
393 0 : return (float)*theActuator.IntValue;
394 : } else {
395 : // follow protocol from EMS manager, where 1.0 is true, 0.0 is false, and anything else is also false
396 0 : if (*theActuator.LogValue) {
397 0 : return 1;
398 : } else {
399 0 : return 0;
400 : }
401 : }
402 : } else {
403 0 : if (thisState->dataGlobal->errorCallback) {
404 0 : std::cout << "ERROR: Actuator handle out of range in getActuatorValue, returning zero but caller should take note and likely abort."
405 0 : << std::endl;
406 : } else {
407 : // must be running from python plugin, need to fatal out once the plugin is done
408 : // throw an error, set the fatal flag, and then return 0
409 0 : EnergyPlus::ShowSevereError(*thisState, fmt::format("Data Exchange API: index error in getActuatorValue; received handle: {}", handle));
410 0 : EnergyPlus::ShowContinueError(
411 : *thisState, "The getActuatorValue function will return 0 for now to allow the plugin to finish, then EnergyPlus will abort");
412 : }
413 0 : thisState->dataPluginManager->apiErrorFlag = true;
414 0 : return 0;
415 : }
416 : }
417 :
418 59 : int getInternalVariableHandle(EnergyPlusState state, const char *type, const char *key)
419 : {
420 59 : int handle = 0;
421 118 : std::string const typeUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(type);
422 118 : std::string const keyUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(key);
423 59 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
424 7747 : for (auto const &availVariable : thisState->dataRuntimeLang->EMSInternalVarsAvailable) { // TODO: this should stop at numEMSInternalVarsAvailable
425 7747 : handle++;
426 15435 : std::string const variableTypeUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(availVariable.DataTypeName);
427 15435 : std::string const variableIDUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(availVariable.UniqueIDName);
428 7747 : if (typeUC == variableTypeUC && keyUC == variableIDUC) {
429 59 : return handle;
430 : }
431 : }
432 0 : return -1;
433 : }
434 :
435 559073 : Real64 getInternalVariableValue(EnergyPlusState state, int handle)
436 : {
437 559073 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
438 559073 : if (handle >= 1 && handle <= (int)thisState->dataRuntimeLang->numEMSInternalVarsAvailable) {
439 1118146 : auto thisVar = thisState->dataRuntimeLang->EMSInternalVarsAvailable(handle);
440 559073 : if (thisVar.PntrVarTypeUsed == EnergyPlus::DataRuntimeLanguage::PtrDataType::Real) {
441 559073 : return *thisVar.RealValue;
442 0 : } else if (thisVar.PntrVarTypeUsed == EnergyPlus::DataRuntimeLanguage::PtrDataType::Integer) {
443 0 : return (Real64)(*thisVar.IntValue);
444 : } else {
445 : // Doesn't look like this struct actually has a logical member type, so uh, throw here?
446 0 : std::cout << "ERROR: Invalid internal variable type here, developer issue., returning zero but caller should take note and likely abort."
447 0 : << std::endl;
448 0 : thisState->dataPluginManager->apiErrorFlag = true;
449 0 : return 0;
450 : }
451 : } else {
452 0 : if (thisState->dataGlobal->errorCallback) {
453 : std::cout << "ERROR: Internal variable handle out of range in getInternalVariableValue, returning zero but caller should take note and "
454 0 : "likely abort."
455 0 : << std::endl;
456 : } else {
457 : // must be running from python plugin, need to fatal out once the plugin is done
458 : // throw an error, set the fatal flag, and then return 0
459 0 : EnergyPlus::ShowSevereError(*thisState,
460 0 : fmt::format("Data Exchange API: index error in getInternalVariableValue; received handle: {}", handle));
461 0 : EnergyPlus::ShowContinueError(
462 : *thisState, "The getInternalVariableValue function will return 0 for now to allow the plugin to finish, then EnergyPlus will abort");
463 : }
464 0 : thisState->dataPluginManager->apiErrorFlag = true;
465 0 : return 0;
466 : }
467 : }
468 :
469 30 : int getPluginGlobalVariableHandle(EnergyPlusState state, const char *name)
470 : {
471 30 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
472 30 : return thisState->dataPluginManager->pluginManager->getGlobalVariableHandle(*thisState, name);
473 : }
474 :
475 56185 : Real64 getPluginGlobalVariableValue(EnergyPlusState state, int handle)
476 : {
477 56185 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
478 56185 : if (handle < 0 || handle > thisState->dataPluginManager->pluginManager->maxGlobalVariableIndex) {
479 : // need to fatal out once the plugin is done
480 : // throw an error, set the fatal flag, and then return 0
481 0 : EnergyPlus::ShowSevereError(
482 0 : *thisState, fmt::format("Data Exchange API: Problem -- index error in getPluginGlobalVariableValue; received handle: {}", handle));
483 0 : EnergyPlus::ShowContinueError(
484 : *thisState, "The getPluginGlobalVariableValue function will return 0 for now to allow the plugin to finish, then EnergyPlus will abort");
485 0 : thisState->dataPluginManager->apiErrorFlag = true;
486 0 : return 0;
487 : }
488 56185 : return thisState->dataPluginManager->pluginManager->getGlobalVariableValue(*thisState, handle);
489 : }
490 :
491 498808 : void setPluginGlobalVariableValue(EnergyPlusState state, int handle, Real64 value)
492 : {
493 498808 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
494 498808 : if (handle < 0 || handle > thisState->dataPluginManager->pluginManager->maxGlobalVariableIndex) {
495 : // need to fatal out once the plugin is done
496 : // throw an error, set the fatal flag, and then return
497 0 : EnergyPlus::ShowSevereError(
498 0 : *thisState, fmt::format("Data Exchange API: Problem -- index error in setPluginGlobalVariableValue; received handle: {}", handle));
499 0 : EnergyPlus::ShowContinueError(
500 : *thisState, "The getPluginGlobalVariableValue function will return to allow the plugin to finish, then EnergyPlus will abort");
501 0 : thisState->dataPluginManager->apiErrorFlag = true;
502 : }
503 498808 : thisState->dataPluginManager->pluginManager->setGlobalVariableValue(*thisState, handle, value);
504 498808 : }
505 :
506 3 : int getPluginTrendVariableHandle(EnergyPlusState state, const char *name)
507 : {
508 3 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
509 3 : return EnergyPlus::PluginManagement::PluginManager::getTrendVariableHandle(*thisState, name);
510 : }
511 :
512 6346 : Real64 getPluginTrendVariableValue(EnergyPlusState state, int handle, int timeIndex)
513 : {
514 6346 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
515 6346 : if (handle < 0 || handle > thisState->dataPluginManager->pluginManager->maxTrendVariableIndex) {
516 : // need to fatal out once the plugin is done
517 : // throw an error, set the fatal flag, and then return
518 0 : EnergyPlus::ShowSevereError(
519 0 : *thisState, fmt::format("Data Exchange API: Problem -- index error in getPluginTrendVariableValue; received handle: {}", handle));
520 0 : EnergyPlus::ShowContinueError(
521 : *thisState, "The getPluginTrendVariableValue function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
522 0 : thisState->dataPluginManager->apiErrorFlag = true;
523 0 : return 0;
524 : }
525 6346 : if (timeIndex < 1 || timeIndex > ((int)EnergyPlus::PluginManagement::PluginManager::getTrendVariableHistorySize(*thisState, handle))) {
526 : // need to fatal out once the plugin is done
527 : // throw an error, set the fatal flag, and then return
528 0 : EnergyPlus::ShowSevereError(
529 : *thisState,
530 0 : fmt::format("Data Exchange API: Problem -- trend history count argument out of range in getPluginTrendVariableValue; received value: {}",
531 : timeIndex));
532 0 : EnergyPlus::ShowContinueError(
533 : *thisState, "The getPluginTrendVariableValue function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
534 0 : thisState->dataPluginManager->apiErrorFlag = true;
535 0 : return 0;
536 : }
537 6346 : return EnergyPlus::PluginManagement::PluginManager::getTrendVariableValue(*thisState, handle, timeIndex);
538 : }
539 :
540 2016 : Real64 getPluginTrendVariableAverage(EnergyPlusState state, int handle, int count)
541 : {
542 2016 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
543 2016 : if (handle < 0 || handle > thisState->dataPluginManager->pluginManager->maxTrendVariableIndex) {
544 : // need to fatal out once the plugin is done
545 : // throw an error, set the fatal flag, and then return
546 0 : EnergyPlus::ShowSevereError(
547 0 : *thisState, fmt::format("Data Exchange API: Problem -- index error in getPluginTrendVariableAverage; received handle: {}", handle));
548 0 : EnergyPlus::ShowContinueError(
549 : *thisState, "The getPluginTrendVariableAverage function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
550 0 : thisState->dataPluginManager->apiErrorFlag = true;
551 0 : return 0;
552 : }
553 2016 : if (count < 2 || count > ((int)EnergyPlus::PluginManagement::PluginManager::getTrendVariableHistorySize(*thisState, handle))) {
554 : // need to fatal out once the plugin is done
555 : // throw an error, set the fatal flag, and then return
556 0 : EnergyPlus::ShowSevereError(
557 : *thisState,
558 0 : fmt::format(
559 : "Data Exchange API: Problem -- trend history count argument out of range in getPluginTrendVariableAverage; received value: {}",
560 : count));
561 0 : EnergyPlus::ShowContinueError(
562 : *thisState, "The getPluginTrendVariableAverage function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
563 0 : thisState->dataPluginManager->apiErrorFlag = true;
564 0 : return 0;
565 : }
566 2016 : return EnergyPlus::PluginManagement::PluginManager::getTrendVariableAverage(*thisState, handle, count);
567 : }
568 :
569 0 : Real64 getPluginTrendVariableMin(EnergyPlusState state, int handle, int count)
570 : {
571 0 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
572 0 : if (handle < 0 || handle > thisState->dataPluginManager->pluginManager->maxTrendVariableIndex) {
573 : // need to fatal out once the plugin is done
574 : // throw an error, set the fatal flag, and then return
575 0 : EnergyPlus::ShowSevereError(
576 0 : *thisState, fmt::format("Data Exchange API: Problem -- index error in getPluginTrendVariableMin; received handle: {}", handle));
577 0 : EnergyPlus::ShowContinueError(
578 : *thisState, "The getPluginTrendVariableMin function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
579 0 : thisState->dataPluginManager->apiErrorFlag = true;
580 0 : return 0;
581 : }
582 0 : if (count < 2 || count > ((int)EnergyPlus::PluginManagement::PluginManager::getTrendVariableHistorySize(*thisState, handle))) {
583 : // need to fatal out once the plugin is done
584 : // throw an error, set the fatal flag, and then return
585 0 : EnergyPlus::ShowSevereError(
586 : *thisState,
587 0 : fmt::format("Data Exchange API: Problem -- trend history count argument out of range in getPluginTrendVariableMin; received value: {}",
588 : count));
589 0 : EnergyPlus::ShowContinueError(
590 : *thisState, "The getPluginTrendVariableMin function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
591 0 : thisState->dataPluginManager->apiErrorFlag = true;
592 0 : return 0;
593 : }
594 0 : return EnergyPlus::PluginManagement::PluginManager::getTrendVariableMin(*thisState, handle, count);
595 : }
596 :
597 0 : Real64 getPluginTrendVariableMax(EnergyPlusState state, int handle, int count)
598 : {
599 0 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
600 0 : if (handle < 0 || handle > thisState->dataPluginManager->pluginManager->maxTrendVariableIndex) {
601 : // need to fatal out once the plugin is done
602 : // throw an error, set the fatal flag, and then return
603 0 : EnergyPlus::ShowSevereError(
604 0 : *thisState, fmt::format("Data Exchange API: Problem -- index error in getPluginTrendVariableMax; received handle: {}", handle));
605 0 : EnergyPlus::ShowContinueError(
606 : *thisState, "The getPluginTrendVariableMax function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
607 0 : thisState->dataPluginManager->apiErrorFlag = true;
608 0 : return 0;
609 : }
610 0 : if (count < 2 || count > ((int)EnergyPlus::PluginManagement::PluginManager::getTrendVariableHistorySize(*thisState, handle))) {
611 : // need to fatal out once the plugin is done
612 : // throw an error, set the fatal flag, and then return
613 0 : EnergyPlus::ShowSevereError(
614 : *thisState,
615 0 : fmt::format("Data Exchange API: Problem -- trend history count argument out of range in getPluginTrendVariableMax; received value: {}",
616 : count));
617 0 : EnergyPlus::ShowContinueError(
618 : *thisState, "The getPluginTrendVariableMax function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
619 0 : thisState->dataPluginManager->apiErrorFlag = true;
620 0 : return 0;
621 : }
622 0 : return EnergyPlus::PluginManagement::PluginManager::getTrendVariableMax(*thisState, handle, count);
623 : }
624 :
625 0 : Real64 getPluginTrendVariableSum(EnergyPlusState state, int handle, int count)
626 : {
627 0 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
628 0 : if (handle < 0 || handle > thisState->dataPluginManager->pluginManager->maxTrendVariableIndex) {
629 : // need to fatal out once the plugin is done
630 : // throw an error, set the fatal flag, and then return
631 0 : EnergyPlus::ShowSevereError(
632 0 : *thisState, fmt::format("Data Exchange API: Problem -- index error in getPluginTrendVariableSum; received handle: {}", handle));
633 0 : EnergyPlus::ShowContinueError(
634 : *thisState, "The getPluginTrendVariableSum function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
635 0 : thisState->dataPluginManager->apiErrorFlag = true;
636 0 : return 0;
637 : }
638 0 : if (count < 2 || count > ((int)EnergyPlus::PluginManagement::PluginManager::getTrendVariableHistorySize(*thisState, handle))) {
639 : // need to fatal out once the plugin is done
640 : // throw an error, set the fatal flag, and then return
641 0 : EnergyPlus::ShowSevereError(
642 : *thisState,
643 0 : fmt::format("Data Exchange API: Problem -- trend history count argument out of range in getPluginTrendVariableSum; received value: {}",
644 : count));
645 0 : EnergyPlus::ShowContinueError(
646 : *thisState, "The getPluginTrendVariableSum function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
647 0 : thisState->dataPluginManager->apiErrorFlag = true;
648 0 : return 0;
649 : }
650 0 : return EnergyPlus::PluginManagement::PluginManager::getTrendVariableSum(*thisState, handle, count);
651 : }
652 :
653 3173 : Real64 getPluginTrendVariableDirection(EnergyPlusState state, int handle, int count)
654 : {
655 3173 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
656 3173 : if (handle < 0 || handle > thisState->dataPluginManager->pluginManager->maxTrendVariableIndex) {
657 : // need to fatal out once the plugin is done
658 : // throw an error, set the fatal flag, and then return
659 0 : EnergyPlus::ShowSevereError(
660 0 : *thisState, fmt::format("Data Exchange API: Problem -- index error in getPluginTrendVariableDirection; received handle: {}", handle));
661 0 : EnergyPlus::ShowContinueError(
662 : *thisState, "The getPluginTrendVariableDirection function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
663 0 : thisState->dataPluginManager->apiErrorFlag = true;
664 0 : return 0;
665 : }
666 3173 : if (count < 2 || count > ((int)EnergyPlus::PluginManagement::PluginManager::getTrendVariableHistorySize(*thisState, handle))) {
667 : // need to fatal out once the plugin is done
668 : // throw an error, set the fatal flag, and then return
669 0 : EnergyPlus::ShowSevereError(
670 : *thisState,
671 0 : fmt::format(
672 : "Data Exchange API: Problem -- trend history count argument out of range in getPluginTrendVariableDirection; received value: {}",
673 : count));
674 0 : EnergyPlus::ShowContinueError(
675 : *thisState, "The getPluginTrendVariableDirection function will return 0 to allow the plugin to finish, then EnergyPlus will abort");
676 0 : thisState->dataPluginManager->apiErrorFlag = true;
677 0 : return 0;
678 : }
679 3173 : return EnergyPlus::PluginManagement::PluginManager::getTrendVariableDirection(*thisState, handle, count);
680 : }
681 :
682 0 : int year(EnergyPlusState state)
683 : {
684 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
685 0 : return thisState->dataEnvrn->Year;
686 : }
687 :
688 7355 : int month(EnergyPlusState state)
689 : {
690 7355 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
691 7355 : return thisState->dataEnvrn->Month;
692 : }
693 :
694 4182 : int dayOfMonth(EnergyPlusState state)
695 : {
696 4182 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
697 4182 : return thisState->dataEnvrn->DayOfMonth;
698 : }
699 :
700 8364 : int dayOfWeek(EnergyPlusState state)
701 : {
702 8364 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
703 8364 : return thisState->dataEnvrn->DayOfWeek;
704 : }
705 :
706 4182 : int dayOfYear(EnergyPlusState state)
707 : {
708 4182 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
709 4182 : return thisState->dataEnvrn->DayOfYear;
710 : }
711 :
712 0 : int daylightSavingsTimeIndicator(EnergyPlusState state)
713 : {
714 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
715 0 : return thisState->dataEnvrn->DSTIndicator;
716 : }
717 :
718 8364 : int hour(EnergyPlusState state)
719 : {
720 8364 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
721 8364 : return thisState->dataGlobal->HourOfDay - 1; // no, just stay on 0..23+ DSTadjust ! offset by 1 and daylight savings time
722 : }
723 :
724 0 : Real64 currentTime(EnergyPlusState state)
725 : {
726 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
727 0 : if (thisState->dataHVACGlobal->TimeStepSys < thisState->dataGlobal->TimeStepZone) {
728 : // CurrentTime is for end of zone timestep, need to move back to beginning of current zone timestep, then add on system time elapsed already
729 : // plus current system timestep
730 0 : return thisState->dataGlobal->CurrentTime - thisState->dataGlobal->TimeStepZone + thisState->dataHVACGlobal->SysTimeElapsed +
731 0 : thisState->dataHVACGlobal->TimeStepSys;
732 : } else {
733 0 : return thisState->dataGlobal->CurrentTime;
734 : }
735 : }
736 :
737 0 : int minutes(EnergyPlusState state)
738 : {
739 : // the -1 is to push us to the right minute, but this should be handled cautiously because if we are inside the HVAC iteration loop,
740 : // currentTime() returns a floating point fractional hour, so truncation could put this a few seconds from the expected minute.
741 0 : Real64 currentTimeVal = currentTime(state);
742 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
743 0 : Real64 fractionalHoursIntoTheDay = currentTimeVal - double(thisState->dataGlobal->HourOfDay - 1);
744 0 : Real64 fractionalMinutesIntoTheDay = std::round(fractionalHoursIntoTheDay * 60.0);
745 0 : return (int)(fractionalMinutesIntoTheDay);
746 : }
747 :
748 0 : int numTimeStepsInHour([[maybe_unused]] EnergyPlusState state)
749 : {
750 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
751 0 : return thisState->dataGlobal->NumOfTimeStepInHour;
752 : }
753 :
754 0 : int zoneTimeStepNum([[maybe_unused]] EnergyPlusState state)
755 : {
756 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
757 0 : return thisState->dataGlobal->TimeStep;
758 : }
759 :
760 16728 : int holidayIndex(EnergyPlusState state)
761 : {
762 16728 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
763 16728 : return thisState->dataEnvrn->HolidayIndex;
764 : }
765 :
766 0 : int sunIsUp(EnergyPlusState state)
767 : { // maintain response convention from previous (EMS) implementation
768 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
769 0 : if (thisState->dataEnvrn->SunIsUp) {
770 0 : return 1;
771 : } else {
772 0 : return 0;
773 : }
774 : }
775 :
776 0 : int isRaining(EnergyPlusState state)
777 : {
778 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
779 0 : if (thisState->dataEnvrn->IsRain) {
780 0 : return 1;
781 : } else {
782 0 : return 0;
783 : }
784 : }
785 :
786 2160 : int warmupFlag(EnergyPlusState state)
787 : {
788 2160 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
789 2160 : if (thisState->dataGlobal->WarmupFlag) {
790 1872 : return 1;
791 : } else {
792 288 : return 0;
793 : }
794 : }
795 :
796 0 : Real64 zoneTimeStep(EnergyPlusState state)
797 : {
798 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
799 0 : return thisState->dataGlobal->TimeStepZone;
800 : }
801 :
802 44387 : Real64 systemTimeStep(EnergyPlusState state)
803 : {
804 44387 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
805 44387 : return thisState->dataHVACGlobal->TimeStepSys;
806 : }
807 :
808 0 : int currentEnvironmentNum(EnergyPlusState state)
809 : {
810 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
811 0 : return thisState->dataEnvrn->CurEnvirNum;
812 : }
813 :
814 0 : int kindOfSim(EnergyPlusState state)
815 : {
816 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
817 0 : return static_cast<int>(thisState->dataGlobal->KindOfSim);
818 : }
819 :
820 19 : int getConstructionHandle(EnergyPlusState state, const char *constructionName)
821 : {
822 19 : int handle = 0;
823 38 : std::string const nameUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(constructionName);
824 19 : auto thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
825 418 : for (auto const &construct : thisState->dataConstruction->Construct) {
826 418 : handle++;
827 817 : std::string const thisNameUC = EnergyPlus::UtilityRoutines::MakeUPPERCase(construct.Name);
828 418 : if (nameUC == thisNameUC) {
829 19 : return handle;
830 : }
831 : }
832 0 : return 0;
833 : }
834 :
835 0 : int actualTime(EnergyPlusState)
836 : {
837 0 : std::string datestring;
838 0 : Array1D_int datevalues(8);
839 0 : ObjexxFCL::date_and_time(datestring, _, _, datevalues);
840 0 : return double(sum(datevalues({5, 8})));
841 : }
842 :
843 0 : int actualDateTime(EnergyPlusState)
844 : {
845 0 : std::string datestring;
846 0 : Array1D_int datevalues(8);
847 0 : ObjexxFCL::date_and_time(datestring, _, _, datevalues);
848 0 : return double(sum(datevalues));
849 : }
850 :
851 0 : int todayWeatherIsRainAtTime(EnergyPlusState state, int hour, int timeStepNum)
852 : {
853 0 : int value = 0;
854 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
855 : int returnStatus =
856 0 : EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(*thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayIsRain, value);
857 0 : if (returnStatus != 0) {
858 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
859 0 : thisState->dataPluginManager->apiErrorFlag = true;
860 : }
861 0 : return value;
862 : }
863 0 : int todayWeatherIsSnowAtTime(EnergyPlusState state, int hour, int timeStepNum)
864 : {
865 0 : int value = 0;
866 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
867 : int returnStatus =
868 0 : EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(*thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayIsSnow, value);
869 0 : if (returnStatus != 0) {
870 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
871 0 : thisState->dataPluginManager->apiErrorFlag = true;
872 : }
873 0 : return value;
874 : }
875 0 : Real64 todayWeatherOutDryBulbAtTime(EnergyPlusState state, int hour, int timeStepNum)
876 : {
877 0 : Real64 value = 0;
878 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
879 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
880 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayOutDryBulbTemp, value);
881 0 : if (returnStatus != 0) {
882 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
883 0 : thisState->dataPluginManager->apiErrorFlag = true;
884 : }
885 0 : return value;
886 : }
887 0 : Real64 todayWeatherOutDewPointAtTime(EnergyPlusState state, int hour, int timeStepNum)
888 : {
889 0 : Real64 value = 0;
890 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
891 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
892 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayOutDewPointTemp, value);
893 0 : if (returnStatus != 0) {
894 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
895 0 : thisState->dataPluginManager->apiErrorFlag = true;
896 : }
897 0 : return value;
898 : }
899 0 : Real64 todayWeatherOutBarometricPressureAtTime(EnergyPlusState state, int hour, int timeStepNum)
900 : {
901 0 : Real64 value = 0;
902 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
903 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
904 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayOutBaroPress, value);
905 0 : if (returnStatus != 0) {
906 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
907 0 : thisState->dataPluginManager->apiErrorFlag = true;
908 : }
909 0 : return value;
910 : }
911 0 : Real64 todayWeatherOutRelativeHumidityAtTime(EnergyPlusState state, int hour, int timeStepNum)
912 : {
913 0 : Real64 value = 0;
914 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
915 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
916 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayOutRelHum, value);
917 0 : if (returnStatus != 0) {
918 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
919 0 : thisState->dataPluginManager->apiErrorFlag = true;
920 : }
921 0 : return value;
922 : }
923 0 : Real64 todayWeatherWindSpeedAtTime(EnergyPlusState state, int hour, int timeStepNum)
924 : {
925 0 : Real64 value = 0;
926 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
927 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
928 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayWindSpeed, value);
929 0 : if (returnStatus != 0) {
930 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
931 0 : thisState->dataPluginManager->apiErrorFlag = true;
932 : }
933 0 : return value;
934 : }
935 0 : Real64 todayWeatherWindDirectionAtTime(EnergyPlusState state, int hour, int timeStepNum)
936 : {
937 0 : Real64 value = 0;
938 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
939 : int returnStatus =
940 0 : EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(*thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayWindDir, value);
941 0 : if (returnStatus != 0) {
942 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
943 0 : thisState->dataPluginManager->apiErrorFlag = true;
944 : }
945 0 : return value;
946 : }
947 0 : Real64 todayWeatherSkyTemperatureAtTime(EnergyPlusState state, int hour, int timeStepNum)
948 : {
949 0 : Real64 value = 0;
950 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
951 : int returnStatus =
952 0 : EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(*thisState, hour, timeStepNum, thisState->dataWeatherManager->TodaySkyTemp, value);
953 0 : if (returnStatus != 0) {
954 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
955 0 : thisState->dataPluginManager->apiErrorFlag = true;
956 : }
957 0 : return value;
958 : }
959 0 : Real64 todayWeatherHorizontalIRSkyAtTime(EnergyPlusState state, int hour, int timeStepNum)
960 : {
961 0 : Real64 value = 0;
962 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
963 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
964 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayHorizIRSky, value);
965 0 : if (returnStatus != 0) {
966 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
967 0 : thisState->dataPluginManager->apiErrorFlag = true;
968 : }
969 0 : return value;
970 : }
971 0 : Real64 todayWeatherBeamSolarRadiationAtTime(EnergyPlusState state, int hour, int timeStepNum)
972 : {
973 0 : Real64 value = 0;
974 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
975 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
976 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayBeamSolarRad, value);
977 0 : if (returnStatus != 0) {
978 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
979 0 : thisState->dataPluginManager->apiErrorFlag = true;
980 : }
981 0 : return value;
982 : }
983 0 : Real64 todayWeatherDiffuseSolarRadiationAtTime(EnergyPlusState state, int hour, int timeStepNum)
984 : {
985 0 : Real64 value = 0;
986 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
987 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
988 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayDifSolarRad, value);
989 0 : if (returnStatus != 0) {
990 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
991 0 : thisState->dataPluginManager->apiErrorFlag = true;
992 : }
993 0 : return value;
994 : }
995 0 : Real64 todayWeatherAlbedoAtTime(EnergyPlusState state, int hour, int timeStepNum)
996 : {
997 0 : Real64 value = 0;
998 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
999 : int returnStatus =
1000 0 : EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(*thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayAlbedo, value);
1001 0 : if (returnStatus != 0) {
1002 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1003 0 : thisState->dataPluginManager->apiErrorFlag = true;
1004 : }
1005 0 : return value;
1006 : }
1007 0 : Real64 todayWeatherLiquidPrecipitationAtTime(EnergyPlusState state, int hour, int timeStepNum)
1008 : {
1009 0 : Real64 value = 0;
1010 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1011 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1012 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TodayLiquidPrecip, value);
1013 0 : if (returnStatus != 0) {
1014 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1015 0 : thisState->dataPluginManager->apiErrorFlag = true;
1016 : }
1017 0 : return value;
1018 : }
1019 :
1020 0 : int tomorrowWeatherIsRainAtTime(EnergyPlusState state, int hour, int timeStepNum)
1021 : {
1022 0 : int value = 0;
1023 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1024 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1025 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowIsRain, value);
1026 0 : if (returnStatus != 0) {
1027 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1028 0 : thisState->dataPluginManager->apiErrorFlag = true;
1029 : }
1030 0 : return value;
1031 : }
1032 0 : int tomorrowWeatherIsSnowAtTime(EnergyPlusState state, int hour, int timeStepNum)
1033 : {
1034 0 : int value = 0;
1035 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1036 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1037 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowIsSnow, value);
1038 0 : if (returnStatus != 0) {
1039 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1040 0 : thisState->dataPluginManager->apiErrorFlag = true;
1041 : }
1042 0 : return value;
1043 : }
1044 288 : Real64 tomorrowWeatherOutDryBulbAtTime(EnergyPlusState state, int hour, int timeStepNum)
1045 : {
1046 288 : Real64 value = 0;
1047 288 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1048 288 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1049 576 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowOutDryBulbTemp, value);
1050 288 : if (returnStatus != 0) {
1051 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1052 0 : thisState->dataPluginManager->apiErrorFlag = true;
1053 : }
1054 288 : return value;
1055 : }
1056 0 : Real64 tomorrowWeatherOutDewPointAtTime(EnergyPlusState state, int hour, int timeStepNum)
1057 : {
1058 0 : Real64 value = 0;
1059 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1060 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1061 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowOutDewPointTemp, value);
1062 0 : if (returnStatus != 0) {
1063 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1064 0 : thisState->dataPluginManager->apiErrorFlag = true;
1065 : }
1066 0 : return value;
1067 : }
1068 0 : Real64 tomorrowWeatherOutBarometricPressureAtTime(EnergyPlusState state, int hour, int timeStepNum)
1069 : {
1070 0 : Real64 value = 0;
1071 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1072 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1073 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowOutBaroPress, value);
1074 0 : if (returnStatus != 0) {
1075 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1076 0 : thisState->dataPluginManager->apiErrorFlag = true;
1077 : }
1078 0 : return value;
1079 : }
1080 0 : Real64 tomorrowWeatherOutRelativeHumidityAtTime(EnergyPlusState state, int hour, int timeStepNum)
1081 : {
1082 0 : Real64 value = 0;
1083 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1084 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1085 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowOutRelHum, value);
1086 0 : if (returnStatus != 0) {
1087 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1088 0 : thisState->dataPluginManager->apiErrorFlag = true;
1089 : }
1090 0 : return value;
1091 : }
1092 0 : Real64 tomorrowWeatherWindSpeedAtTime(EnergyPlusState state, int hour, int timeStepNum)
1093 : {
1094 0 : Real64 value = 0;
1095 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1096 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1097 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowWindSpeed, value);
1098 0 : if (returnStatus != 0) {
1099 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1100 0 : thisState->dataPluginManager->apiErrorFlag = true;
1101 : }
1102 0 : return value;
1103 : }
1104 0 : Real64 tomorrowWeatherWindDirectionAtTime(EnergyPlusState state, int hour, int timeStepNum)
1105 : {
1106 0 : Real64 value = 0;
1107 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1108 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1109 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowWindDir, value);
1110 0 : if (returnStatus != 0) {
1111 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1112 0 : thisState->dataPluginManager->apiErrorFlag = true;
1113 : }
1114 0 : return value;
1115 : }
1116 0 : Real64 tomorrowWeatherSkyTemperatureAtTime(EnergyPlusState state, int hour, int timeStepNum)
1117 : {
1118 0 : Real64 value = 0;
1119 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1120 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1121 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowSkyTemp, value);
1122 0 : if (returnStatus != 0) {
1123 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1124 0 : thisState->dataPluginManager->apiErrorFlag = true;
1125 : }
1126 0 : return value;
1127 : }
1128 0 : Real64 tomorrowWeatherHorizontalIRSkyAtTime(EnergyPlusState state, int hour, int timeStepNum)
1129 : {
1130 0 : Real64 value = 0;
1131 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1132 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1133 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowHorizIRSky, value);
1134 0 : if (returnStatus != 0) {
1135 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1136 0 : thisState->dataPluginManager->apiErrorFlag = true;
1137 : }
1138 0 : return value;
1139 : }
1140 0 : Real64 tomorrowWeatherBeamSolarRadiationAtTime(EnergyPlusState state, int hour, int timeStepNum)
1141 : {
1142 0 : Real64 value = 0;
1143 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1144 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1145 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowBeamSolarRad, value);
1146 0 : if (returnStatus != 0) {
1147 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1148 0 : thisState->dataPluginManager->apiErrorFlag = true;
1149 : }
1150 0 : return value;
1151 : }
1152 0 : Real64 tomorrowWeatherDiffuseSolarRadiationAtTime(EnergyPlusState state, int hour, int timeStepNum)
1153 : {
1154 0 : Real64 value = 0;
1155 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1156 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1157 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowDifSolarRad, value);
1158 0 : if (returnStatus != 0) {
1159 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1160 0 : thisState->dataPluginManager->apiErrorFlag = true;
1161 : }
1162 0 : return value;
1163 : }
1164 0 : Real64 tomorrowWeatherAlbedoAtTime(EnergyPlusState state, int hour, int timeStepNum)
1165 : {
1166 0 : Real64 value = 0;
1167 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1168 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1169 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowAlbedo, value);
1170 0 : if (returnStatus != 0) {
1171 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1172 0 : thisState->dataPluginManager->apiErrorFlag = true;
1173 : }
1174 0 : return value;
1175 : }
1176 0 : Real64 tomorrowWeatherLiquidPrecipitationAtTime(EnergyPlusState state, int hour, int timeStepNum)
1177 : {
1178 0 : Real64 value = 0;
1179 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1180 0 : int returnStatus = EnergyPlus::RuntimeLanguageProcessor::TodayTomorrowWeather(
1181 0 : *thisState, hour, timeStepNum, thisState->dataWeatherManager->TomorrowLiquidPrecip, value);
1182 0 : if (returnStatus != 0) {
1183 0 : EnergyPlus::ShowSevereError(*thisState, "Invalid return from weather lookup, check hour and time step argument values are in range.");
1184 0 : thisState->dataPluginManager->apiErrorFlag = true;
1185 : }
1186 0 : return value;
1187 : }
1188 :
1189 0 : Real64 currentSimTime(EnergyPlusState state)
1190 : {
1191 0 : auto *thisState = reinterpret_cast<EnergyPlus::EnergyPlusData *>(state);
1192 0 : Real64 value = (thisState->dataGlobal->DayOfSim - 1) * 24 + currentTime(state);
1193 0 : return value;
1194 2313 : }
|