diff --git a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingElectric.cpp b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingElectric.cpp index 418f5f3b2ca..f509e5c621f 100644 --- a/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingElectric.cpp +++ b/openstudiocore/src/energyplus/ForwardTranslator/ForwardTranslateCoilHeatingElectric.cpp @@ -110,11 +110,13 @@ boost::optional ForwardTranslator::translateCoilHeatingElectric( Coil if( boost::optional node = mo->optionalCast() ) { idfObject.setString(Coil_Heating_ElectricFields::AirOutletNodeName,node->name().get()); + // For now we write the temp setpoint node as the Coil Outlet Node + idfObject.setString(Coil_Heating_ElectricFields::TemperatureSetpointNodeName,node->name().get()); } } // Temperature Setpoint Node Name - + // If it was hardset we actually use that, otherwise keep above default (coil outlet) if( boost::optional node = modelObject.temperatureSetpointNode() ) { idfObject.setString(Coil_Heating_ElectricFields::TemperatureSetpointNodeName,node->name().get()); diff --git a/openstudiocore/src/model/CoilHeatingElectric.cpp b/openstudiocore/src/model/CoilHeatingElectric.cpp index 71df243a0ba..d609132d16f 100644 --- a/openstudiocore/src/model/CoilHeatingElectric.cpp +++ b/openstudiocore/src/model/CoilHeatingElectric.cpp @@ -230,24 +230,12 @@ namespace detail { { if( ! airLoop->demandComponent(node.handle()) ) { - if( StraightComponent_Impl::addToNode( node ) ) - { - if( boost::optional node = outletModelObject()->optionalCast() ) - { - setTemperatureSetpointNode(node.get()); - } - return true; - } + return StraightComponent_Impl::addToNode( node ); } } if ( auto oa = node.airLoopHVACOutdoorAirSystem() ) { - if ( StraightComponent_Impl::addToNode( node ) ) { - if ( auto _node = outletModelObject()->optionalCast() ) { - setTemperatureSetpointNode(_node.get()); - } - return true; - } + return StraightComponent_Impl::addToNode( node ); } return false; diff --git a/openstudiocore/src/model/CoilHeatingElectric.hpp b/openstudiocore/src/model/CoilHeatingElectric.hpp index 0566159d013..b3ffd4f0c1b 100644 --- a/openstudiocore/src/model/CoilHeatingElectric.hpp +++ b/openstudiocore/src/model/CoilHeatingElectric.hpp @@ -104,7 +104,7 @@ class MODEL_API CoilHeatingElectric : public StraightComponent { /** Creates a new equivalent duct object if an object is not already attached. */ AirflowNetworkEquivalentDuct getAirflowNetworkEquivalentDuct(double length, double diameter); - + /** Returns the attached equivalent duct object, if any. */ boost::optional airflowNetworkEquivalentDuct() const; diff --git a/openstudiocore/src/utilities/data/Test/TimeSeries_GTest.cpp b/openstudiocore/src/utilities/data/Test/TimeSeries_GTest.cpp index 0869688e990..99e7e749bf4 100644 --- a/openstudiocore/src/utilities/data/Test/TimeSeries_GTest.cpp +++ b/openstudiocore/src/utilities/data/Test/TimeSeries_GTest.cpp @@ -31,6 +31,7 @@ #include "DataFixture.hpp" #include "../TimeSeries.hpp" +#include "../Vector.hpp" #include "../../time/Date.hpp" #include "../../time/Time.hpp" @@ -1232,3 +1233,464 @@ TEST_F(DataFixture, TimeSeries_Monthly) // Check computations EXPECT_EQ(205804800, startTimeSeries.integrate()); } + +double calculate_sum(int dayStart, int dayEnd) { + return 24 * (dayEnd - dayStart + 1) / 2*(dayEnd + dayStart); +} + +TEST_F(DataFixture, TimeSeries_values_Leap_FullYear) { + + // picking 2012 because it's a Leap Year + int year = 2012; + + // Simulate having a SQL timeseries for a full year, hourly + Date startDate(MonthOfYear(MonthOfYear::Jan), 1, year); + + // Each day has the same value corresponding to the day number (eg 1 for Jan 1, 2 for Jan 2, etc) for all timesteps + int n_vals = 366 * 24; + std::vector values; + values.resize(n_vals); + for (int i=0; i < n_vals; ++i) { + values[i] = (i / 24) + 1; + } + + TimeSeries timeSeries(startDate, openstudio::Time(0,1), openstudio::createVector(values), "lux"); + + Time startTime(0, 0, 1, 0); + Time endTime(0, 24, 0, 0); + + std::vector> daysInMonth = { + {MonthOfYear::Jan, 31}, + {MonthOfYear::Feb, 29}, + {MonthOfYear::Mar, 31}, + {MonthOfYear::Apr, 30}, + {MonthOfYear::May, 31}, + {MonthOfYear::Jun, 30}, + {MonthOfYear::Jul, 31}, + {MonthOfYear::Aug, 31}, + {MonthOfYear::Sep, 30}, + {MonthOfYear::Oct, 31}, + {MonthOfYear::Nov, 30}, + {MonthOfYear::Dec, 31}, + }; + + // Hardcode years + { + int dayStart = 1; + for (const auto& monthEntry: daysInMonth) { + const MonthOfYear& month = monthEntry.first; + const int& ndays= monthEntry.second; + + DateTime startDateTime(Date(month, 1, year), startTime); + DateTime endDateTime(Date(month, ndays, year), endTime); + Vector vals = timeSeries.values(startDateTime, endDateTime); + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + int dayEnd = ndays + dayStart - 1; + // Calculate the Sum and compare it to the values we actually retrieved to ensure we sliced correctly + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + + dayStart += ndays; + + } + } + + // Cannot *not* harcode year because it'll assume a non leap year (2009) and produce a problem with Feb 29 +} + +TEST_F(DataFixture, TimeSeries_values_NonLeap_FullYear) { + + // picking 2011 because it's a non Leap Year + int year = 2011; + + // Simulate having a SQL timeseries for a full year, hourly + Date startDate(MonthOfYear(MonthOfYear::Jan), 1, year); + + // Each day has the same value corresponding to the day number (eg 1 for Jan 1, 2 for Jan 2, etc) for all timesteps + int n_vals = 365 * 24; + std::vector values; + values.resize(n_vals); + for (int i=0; i < n_vals; ++i) { + values[i] = (i / 24) + 1; + } + + TimeSeries timeSeries(startDate, openstudio::Time(0,1), openstudio::createVector(values), "lux"); + + Time startTime(0, 1, 0, 0); + Time endTime(0, 24, 1, 0); + + std::vector> daysInMonth = { + {MonthOfYear::Jan, 31}, + {MonthOfYear::Feb, 28}, + {MonthOfYear::Mar, 31}, + {MonthOfYear::Apr, 30}, + {MonthOfYear::May, 31}, + {MonthOfYear::Jun, 30}, + {MonthOfYear::Jul, 31}, + {MonthOfYear::Aug, 31}, + {MonthOfYear::Sep, 30}, + {MonthOfYear::Oct, 31}, + {MonthOfYear::Nov, 30}, + {MonthOfYear::Dec, 31}, + }; + + // Hardcode years + { + int dayStart = 1; + for (const auto& monthEntry: daysInMonth) { + const MonthOfYear& month = monthEntry.first; + const int& ndays= monthEntry.second; + + + DateTime startDateTime(Date(month, 1, year), startTime); + DateTime endDateTime(Date(month, ndays, year), endTime); + Vector vals = timeSeries.values(startDateTime, endDateTime); + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + int dayEnd = ndays + dayStart - 1; + // Calculate the Sum and compare it to the values we actually retrieved to ensure we sliced correctly + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + + dayStart += ndays; + + } + } + + // Don't hardcode years + { + int dayStart = 1; + for (const auto& monthEntry: daysInMonth) { + const MonthOfYear& month = monthEntry.first; + const int& ndays= monthEntry.second; + + DateTime startDateTime(Date(month, 1), startTime); + DateTime endDateTime(Date(month, ndays), endTime); + Vector vals = timeSeries.values(startDateTime, endDateTime); + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + int dayEnd = ndays + dayStart - 1; + // Calculate the Sum and compare it to the values we actually retrieved to ensure we sliced correctly + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + + dayStart += ndays; + + } + } + +} + +TEST_F(DataFixture, TimeSeries_values_WrapAround_Hardcode) { + + // picking 2011 because it's a not a Leap Year but 2012 is + int year = 2011; + + // Simulate having a SQL timeseries for two full years, one non leap and one leap, hourly + Date startDate(MonthOfYear(MonthOfYear::Jan), 1, year); + + // Each day has the same value corresponding to the day number (eg 1 for Jan 1, 2 for Jan 2, etc) for all timesteps + int n_vals = (365+366) * 24; + std::vector values; + values.resize(n_vals); + for (int i=0; i < n_vals; ++i) { + values[i] = (i / 24) + 1; + } + + TimeSeries timeSeries(startDate, openstudio::Time(0,1), openstudio::createVector(values), "lux"); + + Time startTime(0, 1, 0, 0); + Time endTime(0, 24, 1, 0); + + std::vector> daysInMonth = { + {MonthOfYear::Jan, 31}, + {MonthOfYear::Feb, 28}, + {MonthOfYear::Mar, 31}, + {MonthOfYear::Apr, 30}, + {MonthOfYear::May, 31}, + {MonthOfYear::Jun, 30}, + {MonthOfYear::Jul, 31}, + {MonthOfYear::Aug, 31}, + {MonthOfYear::Sep, 30}, + {MonthOfYear::Oct, 31}, + {MonthOfYear::Nov, 30}, + {MonthOfYear::Dec, 31}, + + {MonthOfYear::Jan, 31}, + {MonthOfYear::Feb, 29}, + {MonthOfYear::Mar, 31}, + {MonthOfYear::Apr, 30}, + {MonthOfYear::May, 31}, + {MonthOfYear::Jun, 30}, + {MonthOfYear::Jul, 31}, + {MonthOfYear::Aug, 31}, + {MonthOfYear::Sep, 30}, + {MonthOfYear::Oct, 31}, + {MonthOfYear::Nov, 30}, + {MonthOfYear::Dec, 31}, + }; + + // Hardcode years + { + int n = 0; + int dayStart = 1; + for (const auto& monthEntry: daysInMonth) { + ++n; + int thisYear = year; + if (n > 12) { + thisYear = year + 1; + } + const MonthOfYear& month = monthEntry.first; + const int& ndays= monthEntry.second; + + DateTime startDateTime(Date(month, 1, thisYear), startTime); + DateTime endDateTime(Date(month, ndays, thisYear), endTime); + Vector vals = timeSeries.values(startDateTime, endDateTime); + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + int dayEnd = ndays + dayStart - 1; + // Calculate the Sum and compare it to the values we actually retrieved to ensure we sliced correctly + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + + dayStart += ndays; + + } + } + + // Try weird stuff now + { + DateTime startDateTime(Date(MonthOfYear::Dec, 1, year), startTime); + DateTime endDateTime(Date(MonthOfYear::Jan, 31, year + 1), endTime); + Vector vals = timeSeries.values(startDateTime, endDateTime); + + int dayStart = 335; + int ndays = 31 + 31; + int dayEnd = ndays + dayStart - 1; + + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + } + + { + DateTime startDateTime(Date(MonthOfYear::Dec, 1, year), startTime); + DateTime endDateTime(Date(MonthOfYear::Mar, 31, year + 1), endTime); + Vector vals = timeSeries.values(startDateTime, endDateTime); + + int dayStart = 335; + int ndays = 31 + 31 + 29 + 31; + int dayEnd = ndays + dayStart - 1; + + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + } + +} + + +TEST_F(DataFixture, TimeSeries_values_WrapAround_NoHardcode) { + + // picking 2011 because it's a not a Leap Year but 2012 is + int year = 2011; + + // Simulate having a SQL timeseries for two full years, one non leap and one leap, hourly + Date startDate(MonthOfYear(MonthOfYear::Jan), 1, year); + + // Each day has the same value corresponding to the day number (eg 1 for Jan 1, 2 for Jan 2, etc) for all timesteps + int n_vals = (365+366) * 24; + std::vector values; + values.resize(n_vals); + for (int i=0; i < n_vals; ++i) { + values[i] = (i / 24) + 1; + } + + TimeSeries timeSeries(startDate, openstudio::Time(0,1), openstudio::createVector(values), "lux"); + + Time startTime(0, 1, 0, 0); + Time endTime(0, 24, 1, 0); + + std::vector> daysInMonth = { + {MonthOfYear::Jan, 31}, + {MonthOfYear::Feb, 28}, + {MonthOfYear::Mar, 31}, + {MonthOfYear::Apr, 30}, + {MonthOfYear::May, 31}, + {MonthOfYear::Jun, 30}, + {MonthOfYear::Jul, 31}, + {MonthOfYear::Aug, 31}, + {MonthOfYear::Sep, 30}, + {MonthOfYear::Oct, 31}, + {MonthOfYear::Nov, 30}, + {MonthOfYear::Dec, 31}, + + {MonthOfYear::Jan, 31}, + {MonthOfYear::Feb, 29}, + {MonthOfYear::Mar, 31}, + {MonthOfYear::Apr, 30}, + {MonthOfYear::May, 31}, + {MonthOfYear::Jun, 30}, + {MonthOfYear::Jul, 31}, + {MonthOfYear::Aug, 31}, + {MonthOfYear::Sep, 30}, + {MonthOfYear::Oct, 31}, + {MonthOfYear::Nov, 30}, + {MonthOfYear::Dec, 31}, + }; + + // Don't Hardcode years: can only retrieve months of first years + { + int n = 0; + int dayStart = 1; + for (const auto& monthEntry: daysInMonth) { + ++n; + int thisYear = year; + if (n > 12) { + break; + } + const MonthOfYear& month = monthEntry.first; + const int& ndays= monthEntry.second; + + DateTime startDateTime(Date(month, 1, thisYear), startTime); + DateTime endDateTime(Date(month, ndays, thisYear), endTime); + Vector vals = timeSeries.values(startDateTime, endDateTime); + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + int dayEnd = ndays + dayStart - 1; + // Calculate the Sum and compare it to the values we actually retrieved to ensure we sliced correctly + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + + dayStart += ndays; + + } + } + + // Try some stuff now + + // No years passed, no leap, end < start + { + DateTime startDateTime(Date(MonthOfYear::Dec, 1), startTime); + DateTime endDateTime(Date(MonthOfYear::Jan, 31), endTime); + Vector vals = timeSeries.values(startDateTime, endDateTime); + + int dayStart = 335; + int ndays = 31 + 31; + int dayEnd = ndays + dayStart - 1; + + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + } + + // No years passed, leap, end < start + { + DateTime startDateTime(Date(MonthOfYear::Dec, 1), startTime); + DateTime endDateTime(Date(MonthOfYear::Mar, 31), endTime); + Vector vals = timeSeries.values(startDateTime, endDateTime); + + int dayStart = 335; + int ndays = 31 + 31 + 29 + 31; + int dayEnd = ndays + dayStart - 1; + + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + } + + // Start Year passed, end year defaulted but after start + { + DateTime startDateTime(Date(MonthOfYear::Jan, 1, year), startTime); + // Expect this to default to Feb 28, year + DateTime endDateTime(Date(MonthOfYear::Feb, 28), endTime); + + Vector vals = timeSeries.values(startDateTime, endDateTime); + + int dayStart = 1; + int ndays = 31 + 28; + int dayEnd = ndays + dayStart - 1; + + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + + } + + // Start Year passed, end year defaulted but before start in terms of Month/Day combo + { + DateTime startDateTime(Date(MonthOfYear::Dec, 1, year), startTime); + // Will default to Jan 31 year+1 + DateTime endDateTime(Date(MonthOfYear::Jan, 31), endTime); + + Vector vals = timeSeries.values(startDateTime, endDateTime); + + int dayStart = 335; + int ndays = 31 + 31; + int dayEnd = ndays + dayStart - 1; + + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + + } + + // Start Year not passed, end year hard assigned + { + // Will default to Jan 1, year + DateTime startDateTime(Date(MonthOfYear::Jan, 1), startTime); + DateTime endDateTime(Date(MonthOfYear::Jan, 31, year), endTime); + + Vector vals = timeSeries.values(startDateTime, endDateTime); + + int dayStart = 1; + int ndays = 31; + int dayEnd = ndays + dayStart - 1; + + EXPECT_EQ(ndays * 24, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + + EXPECT_EQ(calculate_sum(dayStart, dayEnd), openstudio::sum(vals)) + << " Failed between " << startDateTime << " and " << endDateTime; + + } + + // Start Year not passed, end year hard assigned but incoherent (before start) + { + // Will default to Feb 1, year + DateTime startDateTime(Date(MonthOfYear::Feb, 1), startTime); + DateTime endDateTime(Date(MonthOfYear::Jan, 1, year), endTime); + + Vector vals = timeSeries.values(startDateTime, endDateTime); + + EXPECT_EQ(0, vals.size()) + << " Failed between " << startDateTime << " and " << endDateTime; + + } + +} diff --git a/openstudiocore/src/utilities/data/TimeSeries.cpp b/openstudiocore/src/utilities/data/TimeSeries.cpp index 1eb6a93ed00..469fe94d84a 100644 --- a/openstudiocore/src/utilities/data/TimeSeries.cpp +++ b/openstudiocore/src/utilities/data/TimeSeries.cpp @@ -615,39 +615,47 @@ Vector TimeSeries_Impl::values(const DateTime& startDateTime, const DateTime& en { boost::optional calendarYear = m_firstReportDateTime.date().baseYear(); - DateTime startDateTimeCompare = startDateTime; - if (!calendarYear && startDateTime.date().baseYear()) { - startDateTimeCompare = DateTime(Date(startDateTime.date().monthOfYear(), startDateTime.date().dayOfMonth()), startDateTime.time()); - } - - DateTime endDateTimeCompare = endDateTime; - if (!calendarYear && endDateTime.date().baseYear()) { - endDateTimeCompare = DateTime(Date(endDateTime.date().monthOfYear(), endDateTime.date().dayOfMonth()), endDateTime.time()); - } - + // If our timeseries doesn't have a year, we force it to the assumed one DateTime firstReportDateTimeWithYear = m_firstReportDateTime; + int timeSeriesYear = m_firstReportDateTime.date().year(); if (!calendarYear) { - firstReportDateTimeWithYear = DateTime(Date(m_firstReportDateTime.date().monthOfYear(), m_firstReportDateTime.date().dayOfMonth(), m_firstReportDateTime.date().year()), m_firstReportDateTime.time()); + firstReportDateTimeWithYear = DateTime(Date(m_firstReportDateTime.date().monthOfYear(), m_firstReportDateTime.date().dayOfMonth(), timeSeriesYear), m_firstReportDateTime.time()); } + // If our requested start doen't have an assigned year, we default to the one of the **TimeSeries** (whether hard assigned or not) DateTime startDateTimeWithYear = startDateTime; if (!startDateTime.date().baseYear()) { - startDateTimeWithYear = DateTime(Date(startDateTime.date().monthOfYear(), startDateTime.date().dayOfMonth(), startDateTime.date().year()), startDateTime.time()); + startDateTimeWithYear = DateTime(Date(startDateTime.date().monthOfYear(), startDateTime.date().dayOfMonth(), timeSeriesYear), startDateTime.time()); } + // Then if our end doesn't have an assigned year, we default it based on the start one DateTime endDateTimeWithYear = endDateTime; if (!endDateTime.date().baseYear()) { - if (m_wrapAround) { - if (endDateTimeCompare < startDateTimeCompare) { - endDateTimeWithYear = DateTime(Date(endDateTime.date().monthOfYear(), endDateTime.date().dayOfMonth(), endDateTime.date().year() + 1), endDateTime.time()); - } else { - endDateTimeWithYear = DateTime(Date(endDateTime.date().monthOfYear(), endDateTime.date().dayOfMonth(), endDateTime.date().year()), endDateTime.time()); - } + + // Compare on a Month/Day basis only + DateTime startDateTimeCompare = DateTime(Date(startDateTime.date().monthOfYear(), startDateTime.date().dayOfMonth()), startDateTime.time()); + DateTime endDateTimeCompare = DateTime(Date(endDateTime.date().monthOfYear(), endDateTime.date().dayOfMonth()), endDateTime.time()); + + if (endDateTimeCompare <= startDateTimeCompare) { + endDateTimeWithYear = DateTime(Date(endDateTime.date().monthOfYear(), endDateTime.date().dayOfMonth(), startDateTimeWithYear.date().year() + 1), + endDateTime.time()); } else { - endDateTimeWithYear = DateTime(Date(endDateTime.date().monthOfYear(), endDateTime.date().dayOfMonth(), endDateTime.date().year()), endDateTime.time()); + double totalSeconds = (endDateTimeCompare - startDateTimeCompare).totalSeconds(); + endDateTimeWithYear = startDateTimeWithYear + Time(0, 0, 0, totalSeconds); + // endDateTimeWithYear = DateTime(Date(endDateTime.date().monthOfYear(), endDateTime.date().dayOfMonth(), timeSeriesYear), endDateTime.time()); } } + // After our thing, we ensure that we do end up with dates that make sense + if (endDateTimeWithYear < startDateTimeWithYear) { + LOG(Warn, "Incorrect DateTimes passed, ensure that the start and end dates are coherent"); + } + + LOG(Debug, "Initial: startDateTime=" << startDateTime << ", endDateTime=" << endDateTime << + ", m_firstReportDateTime=" << m_firstReportDateTime); + LOG(Debug, "Querying with startDateTimeWithYear=" << startDateTimeWithYear << ", endDateTimeWithYear=" << endDateTimeWithYear + << ", firstReportDateTimeWithYear=" << firstReportDateTimeWithYear); + double startSecondsFromFirstReport = (startDateTimeWithYear - firstReportDateTimeWithYear).totalSeconds(); double endSecondsFromFirstReport = (endDateTimeWithYear - firstReportDateTimeWithYear).totalSeconds(); @@ -665,6 +673,10 @@ Vector TimeSeries_Impl::values(const DateTime& startDateTime, const DateTime& en } result.resize(resultSize, true); + // Warn if empty + if (resultSize == 0) { + LOG(Warn, "The combination of start and end DateTimes you passed resulted in zero values"); + } return result; }