Skip to content

Commit d8026ec

Browse files
authored
Merge pull request #4879 from NREL/schedule-file-rel-path
Schedule:File relative paths
2 parents 4d820d0 + 28a3f30 commit d8026ec

File tree

7 files changed

+244
-11
lines changed

7 files changed

+244
-11
lines changed

resources/model/OpenStudio.idd

+8-1
Original file line numberDiff line numberDiff line change
@@ -5104,13 +5104,20 @@ OS:Schedule:File,
51045104
\key 20
51055105
\key 30
51065106
\key 60
5107-
A7 ; \field Adjust Schedule for Daylight Savings
5107+
A7, \field Adjust Schedule for Daylight Savings
51085108
\note "No" means do not include Daylight Savings Time in the schedule, instead, use the schedule directly from the Schedule:File csv (default)
51095109
\note "Yes" means include Daylight Savings Time to the schedule
51105110
\type choice
51115111
\key Yes
51125112
\key No
51135113
\default Yes
5114+
A8; \field Translate File With Relative Path
5115+
\note "No" means the absolute path of the ExternalFile is resolved and translated to IDF.
5116+
\note "Yes" means only the filename (relative) is translated
5117+
\type choice
5118+
\default No
5119+
\key Yes
5120+
\key No
51145121

51155122
\group OpenStudio Geometry
51165123

src/energyplus/ForwardTranslator/ForwardTranslateScheduleFile.cpp

+1-10
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,8 @@ namespace energyplus {
4040
idfObject.setString(openstudio::Schedule_FileFields::ScheduleTypeLimitsName, idfScheduleTypeLimits->name().get());
4141
}
4242
}
43-
44-
path filePath = modelObject.externalFile().filePath();
45-
if (!exists(filePath)) {
46-
LOG(Warn, "Cannot find file \"" << filePath << "\"");
47-
} else {
48-
// make the path correct for this system
49-
filePath = system_complete(filePath);
50-
}
51-
5243
// DLM: this path is going to be in the temp dir, might want to fix it up when saving model temp dir
53-
idfObject.setString(openstudio::Schedule_FileFields::FileName, toString(filePath));
44+
idfObject.setString(openstudio::Schedule_FileFields::FileName, toString(modelObject.translatedFilePath()));
5445

5546
idfObject.setInt(openstudio::Schedule_FileFields::ColumnNumber, modelObject.columnNumber());
5647
idfObject.setInt(openstudio::Schedule_FileFields::RowstoSkipatTop, modelObject.rowstoSkipatTop());

src/energyplus/Test/ScheduleInterval_GTest.cpp

+141
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,19 @@
2020
#include "../../model/ScheduleFixedInterval_Impl.hpp"
2121
#include "../../model/ScheduleVariableInterval.hpp"
2222
#include "../../model/ScheduleVariableInterval_Impl.hpp"
23+
#include "../../model/ExternalFile.hpp"
24+
#include "../../model/ExternalFile_Impl.hpp"
2325
#include "../../model/ScheduleFile.hpp"
2426
#include "../../model/ScheduleFile_Impl.hpp"
2527
#include "../../model/YearDescription.hpp"
2628
#include "../../model/YearDescription_Impl.hpp"
2729

2830
#include <utilities/idd/IddEnums.hxx>
2931

32+
#include "../../utilities/core/PathHelpers.hpp"
33+
#include "../../utilities/core/Filesystem.hpp"
34+
#include <resources.hxx>
35+
3036
#include <boost/regex.hpp>
3137

3238
#include <sstream>
@@ -1850,3 +1856,138 @@ TEST_F(EnergyPlusFixture, DISABLED_ForwardTranslator_ScheduleVariableInterval_Da
18501856
// check that there were XX untils
18511857
//EXPECT_EQ(864, numUntils);
18521858
}
1859+
1860+
TEST_F(EnergyPlusFixture, ScheduleFileRelativePath) {
1861+
1862+
openstudio::path absoluteScheduleFilePath = resourcesPath() / toPath("model/schedulefile.csv");
1863+
ASSERT_TRUE(openstudio::filesystem::is_regular_file(absoluteScheduleFilePath));
1864+
ASSERT_TRUE(absoluteScheduleFilePath.is_absolute());
1865+
1866+
openstudio::path curDirPath = boost::filesystem::current_path();
1867+
openstudio::path relativeScheduleFilePath = openstudio::filesystem::relative(absoluteScheduleFilePath, curDirPath);
1868+
ASSERT_TRUE(relativeScheduleFilePath.is_relative());
1869+
1870+
// ScheduleFile(external_file(/abs/path))
1871+
{
1872+
Model model;
1873+
EXPECT_EQ(0u, model.getConcreteModelObjects<ExternalFile>().size());
1874+
EXPECT_EQ(0u, model.getConcreteModelObjects<ScheduleFile>().size());
1875+
1876+
boost::optional<ExternalFile> external_file = ExternalFile::getExternalFile(model, openstudio::toString(absoluteScheduleFilePath));
1877+
ASSERT_TRUE(external_file);
1878+
ScheduleFile schedule(*external_file);
1879+
EXPECT_TRUE(schedule.setTranslateFileWithRelativePath(true));
1880+
EXPECT_TRUE(schedule.translateFileWithRelativePath());
1881+
EXPECT_EQ(1u, model.getConcreteModelObjects<ScheduleFile>().size());
1882+
EXPECT_EQ(1u, model.getConcreteModelObjects<ExternalFile>().size());
1883+
ExternalFile externalfile = schedule.externalFile();
1884+
EXPECT_EQ(1u, externalfile.scheduleFiles().size());
1885+
EXPECT_EQ(openstudio::toString(absoluteScheduleFilePath.filename()), externalfile.fileName());
1886+
EXPECT_TRUE(toPath(externalfile.fileName()).is_relative());
1887+
EXPECT_FALSE(externalfile.filePath().is_relative());
1888+
EXPECT_NE(toPath(externalfile.fileName()), externalfile.filePath());
1889+
1890+
ForwardTranslator ft;
1891+
Workspace workspace = ft.translateModel(model);
1892+
1893+
std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::Schedule_File);
1894+
ASSERT_EQ(1u, objects.size());
1895+
1896+
boost::optional<std::string> fileName = objects[0].getString(2); // File Name
1897+
ASSERT_TRUE(fileName);
1898+
EXPECT_TRUE(toPath(fileName.get()).is_relative()); // rel path
1899+
EXPECT_NE(externalfile.filePath(), fileName.get());
1900+
}
1901+
1902+
// ScheduleFile(external_file(/rel/path))
1903+
{
1904+
Model model;
1905+
EXPECT_EQ(0u, model.getConcreteModelObjects<ExternalFile>().size());
1906+
EXPECT_EQ(0u, model.getConcreteModelObjects<ScheduleFile>().size());
1907+
1908+
boost::optional<ExternalFile> external_file = ExternalFile::getExternalFile(model, openstudio::toString(relativeScheduleFilePath));
1909+
ASSERT_TRUE(external_file);
1910+
ScheduleFile schedule(*external_file);
1911+
EXPECT_TRUE(schedule.setTranslateFileWithRelativePath(true));
1912+
EXPECT_TRUE(schedule.translateFileWithRelativePath());
1913+
EXPECT_EQ(1u, model.getConcreteModelObjects<ScheduleFile>().size());
1914+
EXPECT_EQ(1u, model.getConcreteModelObjects<ExternalFile>().size());
1915+
ExternalFile externalfile = schedule.externalFile();
1916+
EXPECT_EQ(1u, externalfile.scheduleFiles().size());
1917+
EXPECT_EQ(openstudio::toString(relativeScheduleFilePath.filename()), externalfile.fileName());
1918+
EXPECT_TRUE(toPath(externalfile.fileName()).is_relative());
1919+
EXPECT_FALSE(externalfile.filePath().is_relative());
1920+
EXPECT_NE(toPath(externalfile.fileName()), externalfile.filePath());
1921+
1922+
ForwardTranslator ft;
1923+
Workspace workspace = ft.translateModel(model);
1924+
1925+
std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::Schedule_File);
1926+
ASSERT_EQ(1u, objects.size());
1927+
1928+
boost::optional<std::string> fileName = objects[0].getString(2); // File Name
1929+
ASSERT_TRUE(fileName);
1930+
EXPECT_TRUE(toPath(fileName.get()).is_relative()); // rel path
1931+
EXPECT_NE(externalfile.filePath(), fileName.get());
1932+
}
1933+
1934+
// ScheduleFile(model, /abs/path)
1935+
{
1936+
Model model;
1937+
EXPECT_EQ(0u, model.getConcreteModelObjects<ExternalFile>().size());
1938+
EXPECT_EQ(0u, model.getConcreteModelObjects<ScheduleFile>().size());
1939+
1940+
ScheduleFile schedule(model, openstudio::toString(absoluteScheduleFilePath));
1941+
EXPECT_TRUE(schedule.setTranslateFileWithRelativePath(true));
1942+
EXPECT_TRUE(schedule.translateFileWithRelativePath());
1943+
EXPECT_EQ(1u, model.getConcreteModelObjects<ScheduleFile>().size());
1944+
EXPECT_EQ(1u, model.getConcreteModelObjects<ExternalFile>().size());
1945+
ExternalFile externalfile = schedule.externalFile();
1946+
EXPECT_EQ(1u, externalfile.scheduleFiles().size());
1947+
EXPECT_EQ(openstudio::toString(absoluteScheduleFilePath), externalfile.fileName());
1948+
EXPECT_FALSE(toPath(externalfile.fileName()).is_relative());
1949+
EXPECT_FALSE(externalfile.filePath().is_relative());
1950+
EXPECT_EQ(toPath(externalfile.fileName()), externalfile.filePath());
1951+
1952+
ForwardTranslator ft;
1953+
Workspace workspace = ft.translateModel(model);
1954+
1955+
std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::Schedule_File);
1956+
ASSERT_EQ(1u, objects.size());
1957+
1958+
boost::optional<std::string> fileName = objects[0].getString(2); // File Name
1959+
ASSERT_TRUE(fileName);
1960+
EXPECT_FALSE(toPath(fileName.get()).is_relative()); // abs path
1961+
EXPECT_EQ(externalfile.filePath(), fileName.get());
1962+
}
1963+
1964+
// ScheduleFile(model, /rel/path)
1965+
{
1966+
Model model;
1967+
EXPECT_EQ(0u, model.getConcreteModelObjects<ExternalFile>().size());
1968+
EXPECT_EQ(0u, model.getConcreteModelObjects<ScheduleFile>().size());
1969+
1970+
ScheduleFile schedule(model, openstudio::toString(relativeScheduleFilePath));
1971+
EXPECT_TRUE(schedule.setTranslateFileWithRelativePath(true));
1972+
EXPECT_TRUE(schedule.translateFileWithRelativePath());
1973+
EXPECT_EQ(1u, model.getConcreteModelObjects<ScheduleFile>().size());
1974+
EXPECT_EQ(1u, model.getConcreteModelObjects<ExternalFile>().size());
1975+
ExternalFile externalfile = schedule.externalFile();
1976+
EXPECT_EQ(1u, externalfile.scheduleFiles().size());
1977+
EXPECT_EQ(openstudio::toString(relativeScheduleFilePath), externalfile.fileName());
1978+
EXPECT_TRUE(toPath(externalfile.fileName()).is_relative());
1979+
EXPECT_TRUE(externalfile.filePath().is_relative()) << externalfile.filePath();
1980+
EXPECT_EQ(toPath(externalfile.fileName()), externalfile.filePath());
1981+
1982+
ForwardTranslator ft;
1983+
Workspace workspace = ft.translateModel(model);
1984+
1985+
std::vector<WorkspaceObject> objects = workspace.getObjectsByType(IddObjectType::Schedule_File);
1986+
ASSERT_EQ(1u, objects.size());
1987+
1988+
boost::optional<std::string> fileName = objects[0].getString(2); // File Name
1989+
ASSERT_TRUE(fileName);
1990+
EXPECT_TRUE(toPath(fileName.get()).is_relative()); // rel path
1991+
EXPECT_EQ(externalfile.filePath(), fileName.get());
1992+
}
1993+
}

src/model/ScheduleFile.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,16 @@ namespace model {
233233
return csvFile;
234234
}
235235

236+
bool ScheduleFile_Impl::translateFileWithRelativePath() const {
237+
boost::optional<std::string> value = getString(OS_Schedule_FileFields::TranslateFileWithRelativePath, true);
238+
OS_ASSERT(value);
239+
return openstudio::istringEqual(value.get(), "Yes");
240+
}
241+
242+
bool ScheduleFile_Impl::isTranslateFileWithRelativePathDefaulted() const {
243+
return isEmpty(OS_Schedule_FileFields::TranslateFileWithRelativePath);
244+
}
245+
236246
/* FIXME!
237247
openstudio::TimeSeries ScheduleFile_Impl::timeSeries(unsigned columnIndex) const
238248
{
@@ -376,6 +386,36 @@ namespace model {
376386
}*/
377387
}
378388

389+
bool ScheduleFile_Impl::setTranslateFileWithRelativePath(bool translateFileWithRelativePath) {
390+
bool result = false;
391+
if (translateFileWithRelativePath) {
392+
result = setString(OS_Schedule_FileFields::TranslateFileWithRelativePath, "Yes");
393+
} else {
394+
result = setString(OS_Schedule_FileFields::TranslateFileWithRelativePath, "No");
395+
}
396+
OS_ASSERT(result);
397+
return result;
398+
}
399+
400+
void ScheduleFile_Impl::resetTranslateFileWithRelativePath() {
401+
const bool result = setString(OS_Schedule_FileFields::TranslateFileWithRelativePath, "");
402+
OS_ASSERT(result);
403+
}
404+
405+
openstudio::path ScheduleFile_Impl::translatedFilePath() const {
406+
if (translateFileWithRelativePath()) {
407+
return toPath(externalFile().fileName());
408+
}
409+
openstudio::path filePath = externalFile().filePath();
410+
if (!exists(filePath)) {
411+
LOG(Warn, "Cannot find file \"" << filePath << "\"");
412+
} else {
413+
// make the path correct for this system
414+
filePath = system_complete(filePath);
415+
}
416+
return filePath;
417+
}
418+
379419
} // namespace detail
380420

381421
ScheduleFile::ScheduleFile(const ExternalFile& externalfile, int column, int rowsToSkip)
@@ -477,6 +517,14 @@ namespace model {
477517
return getImpl<detail::ScheduleFile_Impl>()->csvFile();
478518
}
479519

520+
bool ScheduleFile::translateFileWithRelativePath() const {
521+
return getImpl<detail::ScheduleFile_Impl>()->translateFileWithRelativePath();
522+
}
523+
524+
bool ScheduleFile::isTranslateFileWithRelativePathDefaulted() const {
525+
return getImpl<detail::ScheduleFile_Impl>()->isTranslateFileWithRelativePathDefaulted();
526+
}
527+
480528
/* FIXME!
481529
openstudio::TimeSeries ScheduleFile::timeSeries(unsigned columnIndex) const {
482530
return getImpl<detail::ScheduleFile_Impl>()->timeSeries(columnIndex);
@@ -551,6 +599,18 @@ unsigned ScheduleFile::addTimeSeries(const openstudio::TimeSeries& timeSeries) {
551599
getImpl<detail::ScheduleFile_Impl>()->resetAdjustScheduleforDaylightSavings();
552600
}
553601

602+
bool ScheduleFile::setTranslateFileWithRelativePath(bool translateFileWithRelativePath) {
603+
return getImpl<detail::ScheduleFile_Impl>()->setTranslateFileWithRelativePath(translateFileWithRelativePath);
604+
}
605+
606+
void ScheduleFile::resetTranslateFileWithRelativePath() {
607+
getImpl<detail::ScheduleFile_Impl>()->resetTranslateFileWithRelativePath();
608+
}
609+
610+
openstudio::path ScheduleFile::translatedFilePath() const {
611+
return getImpl<detail::ScheduleFile_Impl>()->translatedFilePath();
612+
}
613+
554614
/// @cond
555615
ScheduleFile::ScheduleFile(std::shared_ptr<detail::ScheduleFile_Impl> impl) : ScheduleInterval(std::move(impl)) {}
556616
/// @endcond

src/model/ScheduleFile.hpp

+11
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ namespace model {
8686

8787
boost::optional<CSVFile> csvFile() const;
8888

89+
bool translateFileWithRelativePath() const;
90+
91+
bool isTranslateFileWithRelativePathDefaulted() const;
92+
8993
//@}
9094
/** @name Setters */
9195
//@{
@@ -120,10 +124,17 @@ namespace model {
120124

121125
/* FIXME! unsigned addTimeSeries(const openstudio::TimeSeries& timeSeries); */
122126

127+
bool setTranslateFileWithRelativePath(bool translateFileWithRelativePath);
128+
129+
void resetTranslateFileWithRelativePath();
130+
123131
//@}
124132
/** @name Other */
125133
//@{
126134

135+
// Depending on the value of 'Translate File With Relative Path', returns an absolute or a relative path
136+
openstudio::path translatedFilePath() const;
137+
127138
//@}
128139
protected:
129140
/// @cond

src/model/ScheduleFile_Impl.hpp

+10
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ namespace model {
8888

8989
boost::optional<CSVFile> csvFile() const;
9090

91+
bool translateFileWithRelativePath() const;
92+
93+
bool isTranslateFileWithRelativePathDefaulted() const;
94+
9195
//@}
9296
/** @name Setters */
9397
//@{
@@ -121,10 +125,16 @@ namespace model {
121125
// ensure that this object does not contain the date 2/29
122126
virtual void ensureNoLeapDays() override;
123127

128+
bool setTranslateFileWithRelativePath(bool translateFileWithRelativePath);
129+
130+
void resetTranslateFileWithRelativePath();
131+
124132
//@}
125133
/** @name Other */
126134
//@{
127135

136+
openstudio::path translatedFilePath() const;
137+
128138
//@}
129139
protected:
130140
private:

src/model/test/ScheduleInterval_GTest.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,19 @@ TEST_F(ModelFixture, ScheduleFile) {
320320
schedule3.resetAdjustScheduleforDaylightSavings();
321321
EXPECT_TRUE(schedule3.isAdjustScheduleforDaylightSavingsDefaulted());
322322

323+
EXPECT_FALSE(schedule3.translateFileWithRelativePath());
324+
EXPECT_TRUE(schedule3.isTranslateFileWithRelativePathDefaulted());
325+
EXPECT_EQ(externalfile->filePath(), schedule3.translatedFilePath());
326+
327+
EXPECT_TRUE(schedule3.setTranslateFileWithRelativePath(true));
328+
EXPECT_TRUE(schedule3.translateFileWithRelativePath());
329+
EXPECT_FALSE(schedule3.isTranslateFileWithRelativePathDefaulted());
330+
EXPECT_EQ(toPath(externalfile->fileName()), schedule3.translatedFilePath());
331+
332+
schedule3.resetTranslateFileWithRelativePath();
333+
EXPECT_FALSE(schedule3.translateFileWithRelativePath());
334+
EXPECT_TRUE(schedule3.isTranslateFileWithRelativePathDefaulted());
335+
323336
// shouldn't create a new object
324337
boost::optional<ExternalFile> externalfile2 = ExternalFile::getExternalFile(model, openstudio::toString(p));
325338
ASSERT_TRUE(externalfile2);

0 commit comments

Comments
 (0)