Repository navigation
C API getMeterHandle() can't return handle for first meter #11522
Description
Issue overview
There's a small bug in the C API for getMeterHandle().
The code here expects EnergyPlus::GetMeterIndex() to return 0 if the meter is not found. However 0 IS a valid result. EnergyPlus::GetMeterIndex() returns -1 when the meter is not found.
EnergyPlus/src/EnergyPlus/api/datatransfer.cc
Lines 385 to 395 in e84d72a
| int getMeterHandle(EnergyPlusState state, const char *meterName) | |
| { | |
| auto *thisState = static_cast<EnergyPlus::EnergyPlusData *>(state); | |
| std::string const meterNameUC = EnergyPlus::Util::makeUPPER(meterName); | |
| const int i = EnergyPlus::GetMeterIndex(*thisState, meterNameUC); | |
| if (i == 0) { | |
| // inside E+, zero is meaningful, but through the API, I want to use negative one as a signal of a bad lookup | |
| return -1; | |
| } | |
| return i; | |
| } |
There are some stale docstrings but you can see the -1 on the end of line 4112
EnergyPlus/src/EnergyPlus/OutputProcessor.cc
Lines 4097 to 4113 in e84d72a
| int GetMeterIndex(EnergyPlusData const &state, std::string const &name) | |
| { | |
| // FUNCTION INFORMATION: | |
| // AUTHOR Linda K. Lawrie | |
| // DATE WRITTEN August 2002 | |
| // PURPOSE OF THIS FUNCTION: | |
| // This function returns a index to the meter "number" (aka assigned report number) | |
| // for the meter name. If none active for this run, a zero is returned. This is used later to | |
| // obtain a meter "value". | |
| auto const &op = state.dataOutputProcessor; | |
| auto found = op->meterMap.find(name); | |
| return (found != op->meterMap.end()) ? found->second : -1; | |
| } // GetMeterIndex() |
Because of this, I can't get the Electricity:Facility meter (which tends to be the first) for my simulation.
The fix should be as simple as removing the if (i == 0) block in datatransfer.cc.
Operating System (Multiple choices)
Any, Ubuntu
Operating System Version
24.04
Version of EnergyPlus
26.1.0
Unmethours link or helpdesk ticket number
N/A
Defect file
Here's a minimal example to reproduce the problem. The python wrapper just passes the values through, so hit's the same problem.
import sys
ENERGYPLUS_INSTALL_DIR = "/root/energyplus"
sys.path.insert(0, ENERGYPLUS_INSTALL_DIR)
from pyenergyplus.api import EnergyPlusAPI
api = EnergyPlusAPI()
state = api.state_manager.new_state()
def handle_step(state):
facility_handle = api.exchange.get_meter_handle(state, "Electricity:Facility") # <- This SHOULD return 0, but it returns -1
building_handle = api.exchange.get_meter_handle(state, "Electricity:Building")
facility_value = api.exchange.get_meter_value(state, 0) # <- Passing 0 explicitly returns the correct value
building_value = api.exchange.get_meter_value(state, building_handle)
print({
'facility_handle': facility_handle,
'building_handle': building_handle,
'facility_value': facility_value,
'building_value': building_value,
})
api.runtime.callback_after_predictor_after_hvac_managers(state, handle_step)
api.runtime.run_energyplus(state, [
'--output-directory', 'output',
'--weather', ENERGYPLUS_INSTALL_DIR + '/WeatherData/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw',
ENERGYPLUS_INSTALL_DIR + '/ExampleFiles/5ZoneAirCooled.idf',
])
Activity