Skip to content

C API getMeterHandle() can't return handle for first meter #11522

@secretmike

Description

@secretmike

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.

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

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',
])

Metadata

Metadata

Assignees

Labels

TriageIssue needs to be assessed and labeled, further information on reported might be neededUnconfirmedDefectDefect has not yet confirmed to be an actual issue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions