CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-openstudio

Cross-platform collection of software tools to support whole building energy modeling using EnergyPlus and advanced daylight analysis using Radiance

Pending
Overview
Eval results
Files

workflow.mddocs/

Workflow Management

Orchestration of complete building simulation workflows from initial model through results processing. The workflow system manages the complete analysis pipeline including model measures, EnergyPlus simulation, and reporting measures with comprehensive error handling and progress tracking.

Capabilities

Workflow Orchestration

Main workflow coordination class managing the complete simulation pipeline.

/**
 * Main workflow orchestrator for complete building simulation workflows
 */
class OSWorkflow {
public:
  // Constructors
  OSWorkflow();
  explicit OSWorkflow(const Path& oswPath);
  explicit OSWorkflow(const WorkflowJSON& workflowJSON);
  
  // Workflow execution
  bool run();
  bool run(const Path& oswPath);
  
  // Workflow configuration
  WorkflowJSON workflowJSON() const;
  void setWorkflowJSON(const WorkflowJSON& workflowJSON);
  
  // Model and simulation access
  boost::optional<Model> model() const;
  boost::optional<Workspace> workspace() const;
  boost::optional<SqlFile> sqlFile() const;
  
  // Results and logging
  std::vector<LogMessage> errors() const;
  std::vector<LogMessage> warnings() const;
  std::vector<LogMessage> info() const;
  
  // Workflow state
  bool completed() const;
  std::string completedStatus() const;
  
  // Progress tracking
  void setProgressCallback(std::function<void(int)> callback);
  
  // Step-by-step execution
  bool runInitialization();
  bool runOpenStudioMeasures();
  bool runTranslator();
  bool runEnergyPlus();
  bool runReportingMeasures();
  bool runCleanup();
  
  // Working directory management
  Path rootDirectory() const;
  Path runDirectory() const;
  void setRunDirectory(const Path& runDirectory);
  
  // Simulation files
  Path osmPath() const;
  Path idfPath() const;
  boost::optional<Path> sqlPath() const;
  boost::optional<Path> epwPath() const;
};

Usage Examples:

#include <openstudio/workflow/OSWorkflow.hpp>
#include <openstudio/utilities/filetypes/WorkflowJSON.hpp>

using namespace openstudio;

// Simple workflow execution
OSWorkflow workflow;

// Load workflow configuration
WorkflowJSON workflowJSON = WorkflowJSON::load(Path("simulation_workflow.osw")).get();
workflow.setWorkflowJSON(workflowJSON);

// Run complete workflow
bool success = workflow.run();

if (success) {
  // Access results
  boost::optional<Model> finalModel = workflow.model();
  boost::optional<SqlFile> results = workflow.sqlFile();
  
  if (results) {
    std::cout << "Simulation completed successfully" << std::endl;
  }
} else {
  // Handle errors
  std::vector<LogMessage> errors = workflow.errors();
  for (const auto& error : errors) {
    std::cout << "Workflow Error: " << error.logMessage() << std::endl;
  }
}

Workflow JSON Configuration

JSON-based workflow configuration and serialization.

/**
 * JSON-based workflow configuration
 */
class WorkflowJSON {
public:
  // Constructors
  WorkflowJSON();
  WorkflowJSON(const Path& seedFile, const Path& weatherFile);
  
  // File I/O
  static boost::optional<WorkflowJSON> load(const Path& path);
  bool save(const Path& path) const;
  bool saveAs(const Path& path);
  
  // Seed file (starting model)
  boost::optional<Path> seedFile() const;
  bool setSeedFile(const Path& seedFile);
  void resetSeedFile();
  
  // Weather file
  boost::optional<Path> weatherFile() const;
  bool setWeatherFile(const Path& weatherFile);
  void resetWeatherFile();
  
  // Measure steps
  std::vector<MeasureStep> measures() const;
  bool addMeasure(const MeasureStep& measureStep);
  bool insertMeasure(int index, const MeasureStep& measureStep);
  bool removeMeasure(int index);
  void clearMeasures();
  
  // File paths
  std::vector<Path> filePaths() const;
  bool addFilePath(const Path& filePath);
  
  // Run options
  boost::optional<RunOptions> runOptions() const;
  void setRunOptions(const RunOptions& runOptions);
  
  // Root directory
  boost::optional<Path> rootDirectory() const;
  void setRootDirectory(const Path& rootDirectory);
  
  // JSON access
  std::string string() const;
  Json::Value toJSON() const;
  
  // Validation
  bool isValid() const;
  std::vector<std::string> errors() const;
};

/**
 * Individual measure step configuration
 */
class MeasureStep {
public:
  // Constructors
  MeasureStep();
  MeasureStep(const std::string& measureDirName);
  MeasureStep(const BCLMeasure& bclMeasure);
  
  // Measure identification
  std::string measureDirName() const;
  void setMeasureDirName(const std::string& measureDirName);
  
  boost::optional<std::string> name() const;
  void setName(const std::string& name);
  
  boost::optional<std::string> description() const;
  void setDescription(const std::string& description);
  
  // Measure arguments
  std::map<std::string, OSArgument> arguments() const;
  bool setArgument(const OSArgument& argument);
  bool setArgument(const std::string& name, const std::string& value);
  bool setArgument(const std::string& name, double value);
  bool setArgument(const std::string& name, int value);
  bool setArgument(const std::string& name, bool value);
  
  // Step properties
  boost::optional<MeasureType> measureType() const;
  void setMeasureType(MeasureType measureType);
  
  // Results
  boost::optional<StepResult> result() const;
  void setResult(const StepResult& result);
  void resetResult();
};

/**
 * Workflow run options and simulation settings
 */
class RunOptions {
public:
  // Constructors
  RunOptions();
  
  // EnergyPlus options
  boost::optional<bool> debug() const;
  void setDebug(bool debug);
  
  boost::optional<bool> fastExecution() const;
  void setFastExecution(bool fastExecution);
  
  boost::optional<bool> preserveRunDir() const;
  void setPreserveRunDir(bool preserveRunDir);
  
  boost::optional<bool> cleanup() const;
  void setCleanup(bool cleanup);
  
  // Simulation options
  boost::optional<int> maxDatapoints() const;
  void setMaxDatapoints(int maxDatapoints);
  
  boost::optional<int> numParallel() const;
  void setNumParallel(int numParallel);
  
  // Custom options
  std::map<std::string, std::string> customOptions() const;
  void setCustomOption(const std::string& key, const std::string& value);
};

Workflow Steps

Individual workflow step implementations for different phases of simulation.

/**
 * Base class for workflow steps
 */
class WorkflowStep {
public:
  // Step identification
  virtual std::string stepName() const = 0;
  virtual std::string stepDescription() const = 0;
  
  // Execution
  virtual StepResult run(OSWorkflow& workflow) = 0;
  
  // Step type
  virtual WorkflowStepType stepType() const = 0;
};

/**
 * Initialization step - validates inputs and sets up workflow
 */
class RunInitialization : public WorkflowStep {
public:
  RunInitialization();
  
  virtual std::string stepName() const override { return "Initialization"; }
  virtual std::string stepDescription() const override { 
    return "Initialize workflow and validate inputs"; 
  }
  
  virtual StepResult run(OSWorkflow& workflow) override;
  virtual WorkflowStepType stepType() const override { return WorkflowStepType::Initialization; }
};

/**
 * OpenStudio measures step - applies model measures
 */
class RunOpenStudioMeasures : public WorkflowStep {
public:
  RunOpenStudioMeasures();
  
  virtual std::string stepName() const override { return "OpenStudio Measures"; }
  virtual std::string stepDescription() const override { 
    return "Apply OpenStudio model measures"; 
  }
  
  virtual StepResult run(OSWorkflow& workflow) override;
  virtual WorkflowStepType stepType() const override { return WorkflowStepType::ModelMeasures; }
  
  // Measure filtering
  void setMeasureFilter(std::function<bool(const MeasureStep&)> filter);
};

/**
 * Translation step - converts OpenStudio model to EnergyPlus IDF
 */
class RunTranslator : public WorkflowStep {
public:
  RunTranslator();
  
  virtual std::string stepName() const override { return "Forward Translator"; }
  virtual std::string stepDescription() const override { 
    return "Translate OpenStudio model to EnergyPlus IDF"; 
  }
  
  virtual StepResult run(OSWorkflow& workflow) override;
  virtual WorkflowStepType stepType() const override { return WorkflowStepType::Translation; }
  
  // Translation options
  void setTranslationOptions(const ForwardTranslatorOptions& options);
};

/**
 * EnergyPlus simulation step
 */
class RunEnergyPlus : public WorkflowStep {
public:
  RunEnergyPlus();
  
  virtual std::string stepName() const override { return "EnergyPlus"; }
  virtual std::string stepDescription() const override { 
    return "Run EnergyPlus simulation"; 
  }
  
  virtual StepResult run(OSWorkflow& workflow) override;
  virtual WorkflowStepType stepType() const override { return WorkflowStepType::Simulation; }
  
  // Simulation options
  void setEnergyPlusPath(const Path& energyPlusPath);
  void setNumThreads(int numThreads);
};

/**
 * Reporting measures step - processes simulation results
 */
class RunReportingMeasures : public WorkflowStep {
public:
  RunReportingMeasures();
  
  virtual std::string stepName() const override { return "Reporting Measures"; }
  virtual std::string stepDescription() const override { 
    return "Apply reporting measures to process results"; 
  }
  
  virtual StepResult run(OSWorkflow& workflow) override;
  virtual WorkflowStepType stepType() const override { return WorkflowStepType::ReportingMeasures; }
};

// Workflow step type enumeration
enum class WorkflowStepType {
  Initialization,
  ModelMeasures,
  EnergyPlusMeasures,
  Translation, 
  Simulation,
  ReportingMeasures,
  Cleanup
};

Results and Status Tracking

Comprehensive result tracking and status management for workflow execution.

/**
 * Step execution result
 */
class StepResult {
public:
  // Result status
  enum class Status {
    NotStarted,
    Running,
    Success,
    Fail,
    Skip,
    NA  // Not Applicable
  };
  
  // Constructors
  StepResult();
  StepResult(Status initialStatus);
  
  // Status management
  Status status() const;
  void setStatus(Status status);
  
  std::string statusDescription() const;
  void setStatusDescription(const std::string& description);
  
  // Execution details
  boost::optional<DateTime> startTime() const;
  void setStartTime(const DateTime& startTime);
  
  boost::optional<DateTime> endTime() const;
  void setEndTime(const DateTime& endTime);
  
  boost::optional<double> elapsedTime() const;
  
  // Error and warning messages
  std::vector<LogMessage> errors() const;
  void addError(const LogMessage& error);
  
  std::vector<LogMessage> warnings() const;
  void addWarning(const LogMessage& warning);
  
  std::vector<LogMessage> info() const;
  void addInfo(const LogMessage& info);
  
  // Step outputs
  std::vector<StepFile> stepFiles() const;
  void addStepFile(const StepFile& stepFile);
  
  std::vector<OSAttribute> stepValues() const;
  void addStepValue(const OSAttribute& stepValue);
  
  // Initial and final conditions
  boost::optional<std::string> initialCondition() const;
  void setInitialCondition(const std::string& condition);
  
  boost::optional<std::string> finalCondition() const;
  void setFinalCondition(const std::string& condition);
};

/**
 * File output from workflow steps
 */
class StepFile {
public:
  // Constructors
  StepFile();
  StepFile(const Path& path);
  
  // File properties
  Path path() const;
  void setPath(const Path& path);
  
  std::string displayName() const;
  void setDisplayName(const std::string& displayName);
  
  boost::optional<std::string> description() const;
  void setDescription(const std::string& description);
  
  // File type
  std::string fileType() const;
  void setFileType(const std::string& fileType);
  
  // Usage type (input, output, resource)
  std::string usageType() const;
  void setUsageType(const std::string& usageType);
};

/**
 * Workflow progress tracking
 */
class WorkflowProgress {
public:
  WorkflowProgress();
  
  // Overall progress
  double overallProgress() const;
  void setOverallProgress(double progress);
  
  // Current step
  boost::optional<WorkflowStepType> currentStep() const;
  void setCurrentStep(WorkflowStepType step);
  
  double stepProgress() const;
  void setStepProgress(double progress);
  
  std::string currentActivity() const;
  void setCurrentActivity(const std::string& activity);
  
  // Step results
  std::vector<StepResult> stepResults() const;
  void addStepResult(const StepResult& result);
  
  // Callback registration
  void setProgressCallback(std::function<void(double)> callback);
  void setStepCallback(std::function<void(WorkflowStepType, double, const std::string&)> callback);
};

Parallel Workflow Execution

Support for parallel workflow execution and datapoint management.

/**
 * Parallel workflow execution for multiple datapoints
 */
class ParallelWorkflow {
public:
  // Constructor
  ParallelWorkflow();
  ParallelWorkflow(int numParallel);
  
  // Datapoint management
  void addDatapoint(const WorkflowJSON& datapoint);
  void addDatapoints(const std::vector<WorkflowJSON>& datapoints);
  
  std::vector<WorkflowJSON> datapoints() const;
  int numDatapoints() const;
  
  // Execution settings
  int numParallel() const;
  void setNumParallel(int numParallel);
  
  // Execute all datapoints
  bool run();
  bool run(const Path& outputDirectory);
  
  // Results access
  std::vector<StepResult> results() const;
  StepResult result(int datapointIndex) const;
  
  bool allSucceeded() const;
  int numSucceeded() const;
  int numFailed() const;
  
  // Progress tracking
  void setProgressCallback(std::function<void(int, int)> callback);
  
  // Cancel execution
  void cancel();
  bool cancelled() const;
};

/**
 * Distributed workflow execution
 */
class DistributedWorkflow {
public:
  DistributedWorkflow();
  
  // Cluster configuration
  void setServerConfig(const std::string& serverUrl, int port);
  void setAuthToken(const std::string& token);
  
  // Job submission
  std::string submitJob(const WorkflowJSON& workflow);
  std::vector<std::string> submitJobs(const std::vector<WorkflowJSON>& workflows);
  
  // Job monitoring
  enum class JobStatus { Queued, Running, Completed, Failed, Cancelled };
  
  JobStatus getJobStatus(const std::string& jobId);
  std::map<std::string, JobStatus> getJobStatuses(const std::vector<std::string>& jobIds);
  
  // Results retrieval
  boost::optional<StepResult> getJobResult(const std::string& jobId);
  std::vector<Path> getJobOutputFiles(const std::string& jobId);
  
  // Job management
  bool cancelJob(const std::string& jobId);
  bool deleteJob(const std::string& jobId);
};

Common Usage Patterns

Basic Workflow Execution

#include <openstudio/workflow/OSWorkflow.hpp>
#include <openstudio/utilities/filetypes/WorkflowJSON.hpp>

using namespace openstudio;

// Create workflow configuration
WorkflowJSON workflowJSON;

// Set seed model and weather file
workflowJSON.setSeedFile(Path("baseline_model.osm"));
workflowJSON.setWeatherFile(Path("weather.epw"));

// Add model measures
MeasureStep improveLighting;
improveLighting.setMeasureDirName("improve_lighting_efficiency");
improveLighting.setArgument("lighting_power_density_reduction", 0.3);
workflowJSON.addMeasure(improveLighting);

MeasureStep improveHVAC;
improveHVAC.setMeasureDirName("improve_hvac_efficiency");
improveHVAC.setArgument("cop_improvement", 0.15);
workflowJSON.addMeasure(improveHVAC);

// Add reporting measure
MeasureStep energyReport;
energyReport.setMeasureDirName("energy_use_summary_report");
workflowJSON.addMeasure(energyReport);

// Set run options
RunOptions runOptions;
runOptions.setPreserveRunDir(true);
runOptions.setDebug(false);
workflowJSON.setRunOptions(runOptions);

// Execute workflow
OSWorkflow workflow;
workflow.setWorkflowJSON(workflowJSON);

std::cout << "Starting workflow execution..." << std::endl;
bool success = workflow.run();

if (success) {
  std::cout << "Workflow completed successfully!" << std::endl;
  
  // Access final results
  boost::optional<SqlFile> sqlFile = workflow.sqlFile();
  if (sqlFile) {
    // Process simulation results
    boost::optional<double> totalEnergy = sqlFile->totalSiteEnergy();
    if (totalEnergy) {
      std::cout << "Total site energy: " << *totalEnergy << " GJ" << std::endl;
    }
  }
  
} else {
  std::cout << "Workflow failed!" << std::endl;
  
  // Print errors
  std::vector<LogMessage> errors = workflow.errors();
  for (const auto& error : errors) {
    std::cout << "Error: " << error.logMessage() << std::endl;
  }
}

Step-by-Step Workflow Execution

#include <openstudio/workflow/OSWorkflow.hpp>

using namespace openstudio;

OSWorkflow workflow(Path("detailed_workflow.osw"));

// Execute workflow step by step with detailed monitoring
std::cout << "Step 1: Initialization..." << std::endl;
if (!workflow.runInitialization()) {
  std::cout << "Initialization failed!" << std::endl;
  return false;
}

std::cout << "Step 2: Applying model measures..." << std::endl;
if (!workflow.runOpenStudioMeasures()) {
  std::cout << "Model measures failed!" << std::endl;
  return false;
}

// Check intermediate model
boost::optional<Model> model = workflow.model();
if (model) {
  std::vector<ThermalZone> zones = model->getConcreteModelObjects<ThermalZone>();
  std::cout << "Model now has " << zones.size() << " thermal zones" << std::endl;
}

std::cout << "Step 3: Translating to EnergyPlus..." << std::endl;
if (!workflow.runTranslator()) {
  std::cout << "Translation failed!" << std::endl;
  return false;
}

std::cout << "Step 4: Running EnergyPlus simulation..." << std::endl;
if (!workflow.runEnergyPlus()) {
  std::cout << "EnergyPlus simulation failed!" << std::endl;
  return false;
}

std::cout << "Step 5: Processing results..." << std::endl;
if (!workflow.runReportingMeasures()) {
  std::cout << "Reporting measures failed!" << std::endl;
  return false;
}

std::cout << "Step 6: Cleanup..." << std::endl;
if (!workflow.runCleanup()) {
  std::cout << "Cleanup failed!" << std::endl;
  return false;
}

std::cout << "All workflow steps completed successfully!" << std::endl;

Parallel Datapoint Execution

#include <openstudio/workflow/ParallelWorkflow.hpp>

using namespace openstudio;

// Create base workflow
WorkflowJSON baseWorkflow;
baseWorkflow.setSeedFile(Path("base_model.osm"));
baseWorkflow.setWeatherFile(Path("weather.epw"));

// Create parametric study
ParallelWorkflow parallelWorkflow(4); // Use 4 parallel processes

std::vector<double> wwrValues = {0.2, 0.3, 0.4, 0.5}; // Window-to-wall ratios
std::vector<double> insulationValues = {0.1, 0.15, 0.2, 0.25}; // Insulation R-values

for (double wwr : wwrValues) {
  for (double insulation : insulationValues) {
    
    // Create datapoint workflow
    WorkflowJSON datapoint = baseWorkflow;
    
    // Add parametric measures
    MeasureStep wwrMeasure;
    wwrMeasure.setMeasureDirName("set_window_to_wall_ratio");
    wwrMeasure.setArgument("wwr", wwr);
    datapoint.addMeasure(wwrMeasure);
    
    MeasureStep insulationMeasure;
    insulationMeasure.setMeasureDirName("set_wall_insulation");
    insulationMeasure.setArgument("r_value", insulation);
    datapoint.addMeasure(insulationMeasure);
    
    // Add to parallel execution
    parallelWorkflow.addDatapoint(datapoint);
  }
}

// Set progress callback
parallelWorkflow.setProgressCallback([](int completed, int total) {
  double progress = (double)completed / total * 100.0;
  std::cout << "Progress: " << completed << "/" << total 
            << " (" << std::fixed << std::setprecision(1) << progress << "%)" << std::endl;
});

// Execute all datapoints
std::cout << "Starting parametric study with " << parallelWorkflow.numDatapoints() << " datapoints..." << std::endl;
bool success = parallelWorkflow.run(Path("parametric_results"));

if (success) {
  std::cout << "Parametric study completed!" << std::endl;
  std::cout << "Successful runs: " << parallelWorkflow.numSucceeded() 
            << "/" << parallelWorkflow.numDatapoints() << std::endl;
            
  // Process results from all datapoints
  std::vector<StepResult> results = parallelWorkflow.results();
  for (size_t i = 0; i < results.size(); ++i) {
    if (results[i].status() == StepResult::Status::Success) {
      std::cout << "Datapoint " << i << " completed successfully" << std::endl;
    } else {
      std::cout << "Datapoint " << i << " failed: " << results[i].statusDescription() << std::endl;
    }
  }
  
} else {
  std::cout << "Parametric study failed!" << std::endl;
}

Custom Workflow Steps

#include <openstudio/workflow/WorkflowStep.hpp>

using namespace openstudio;

/**
 * Custom workflow step for model validation
 */
class ModelValidationStep : public WorkflowStep {
public:
  virtual std::string stepName() const override {
    return "Model Validation";
  }
  
  virtual std::string stepDescription() const override {
    return "Validate model geometry and HVAC systems";
  }
  
  virtual StepResult run(OSWorkflow& workflow) override {
    StepResult result(StepResult::Status::Running);
    
    boost::optional<Model> model = workflow.model();
    if (!model) {
      result.setStatus(StepResult::Status::Fail);
      result.addError(LogMessage(LogLevel::Error, "No model available for validation"));
      return result;
    }
    
    std::vector<std::string> validationIssues;
    
    // Check for spaces without thermal zones
    std::vector<Space> spaces = model->getConcreteModelObjects<Space>();
    for (const auto& space : spaces) {
      if (!space.thermalZone()) {
        validationIssues.push_back("Space '" + space.name().get_value_or("Unnamed") + 
                                 "' is not assigned to a thermal zone");
      }
    }
    
    // Check for surfaces without constructions
    std::vector<Surface> surfaces = model->getConcreteModelObjects<Surface>();
    for (const auto& surface : surfaces) {
      if (!surface.construction()) {
        validationIssues.push_back("Surface '" + surface.name().get_value_or("Unnamed") + 
                                 "' has no construction assigned");
      }
    }
    
    // Report validation results
    if (validationIssues.empty()) {
      result.setStatus(StepResult::Status::Success);
      result.setFinalCondition("Model validation passed with no issues");
    } else {
      result.setStatus(StepResult::Status::Success); // Warnings, not errors
      for (const auto& issue : validationIssues) {
        result.addWarning(LogMessage(LogLevel::Warn, issue));
      }
      result.setFinalCondition("Model validation completed with " + 
                             std::to_string(validationIssues.size()) + " warnings");
    }
    
    return result;
  }
  
  virtual WorkflowStepType stepType() const override {
    return WorkflowStepType::ModelMeasures; // Custom type could be added
  }
};

// Usage in custom workflow
void runCustomWorkflow() {
  OSWorkflow workflow(Path("model.osm"));
  
  // Add custom validation step
  ModelValidationStep validationStep;
  StepResult validationResult = validationStep.run(workflow);
  
  if (validationResult.status() != StepResult::Status::Success) {
    std::cout << "Validation failed, aborting workflow" << std::endl;
    return;
  }
  
  // Continue with standard workflow steps
  workflow.runTranslator();
  workflow.runEnergyPlus();
  workflow.runReportingMeasures();
}

Install with Tessl CLI

npx tessl i tessl/pypi-openstudio

docs

energyplus.md

index.md

measure.md

model.md

radiance.md

utilities.md

workflow.md

tile.json