Cross-platform collection of software tools to support whole building energy modeling using EnergyPlus and advanced daylight analysis using Radiance
npx @tessl/cli install tessl/pypi-openstudio@3.10.00
# OpenStudio
1
2
OpenStudio is a cross-platform collection of software tools to support whole building energy modeling using EnergyPlus and advanced daylight analysis using Radiance. It provides a comprehensive C++ SDK with language bindings for Python, Ruby, C#, and JavaScript, enabling developers to create, modify, and simulate building energy models programmatically. The Python bindings provide the most commonly used interface for building energy modeling workflows.
3
4
## Package Information
5
6
- **Package Name**: openstudio
7
- **Package Type**: PyPI/Python Package (with C++ core)
8
- **Language**: Python (with C++ SDK)
9
- **Installation**: `pip install openstudio`
10
- **Repository**: https://github.com/NREL/OpenStudio
11
- **Documentation**: https://openstudio.net/
12
13
## Core Imports
14
15
**Python (Primary):**
16
```python
17
import openstudio
18
from openstudio import model
19
from openstudio import energyplus
20
from openstudio import measure
21
```
22
23
For specific modules:
24
```python
25
from openstudio.model import Model, Building, Zone, Space
26
from openstudio.energyplus import ForwardTranslator
27
```
28
29
**C++ (Advanced):**
30
```cpp
31
#include <openstudio/model/Model.hpp>
32
#include <openstudio/model/Building.hpp>
33
#include <openstudio/model/Zone.hpp>
34
#include <openstudio/model/Space.hpp>
35
#include <openstudio/energyplus/ForwardTranslator.hpp>
36
#include <openstudio/utilities/core/Path.hpp>
37
```
38
39
## Basic Usage
40
41
**Python (Recommended):**
42
```python
43
import openstudio
44
from openstudio import model
45
from openstudio import energyplus
46
47
# Create a new building model
48
model_obj = model.Model()
49
50
# Get or create the building object
51
building = model_obj.getUniqueModelObject(model.Building)
52
building.setName("Sample Building")
53
54
# Create a thermal zone
55
zone = model.Zone(model_obj)
56
zone.setName("Main Zone")
57
58
# Translate to EnergyPlus
59
forward_translator = energyplus.ForwardTranslator()
60
workspace = forward_translator.translateModel(model_obj)
61
62
# Save to IDF file
63
path = openstudio.Path("building.idf")
64
workspace.save(path, True)
65
```
66
67
**C++ (Advanced):**
68
```cpp
69
#include <openstudio/model/Model.hpp>
70
#include <openstudio/model/Building.hpp>
71
#include <openstudio/model/Zone.hpp>
72
#include <openstudio/energyplus/ForwardTranslator.hpp>
73
74
using namespace openstudio;
75
using namespace openstudio::model;
76
77
// Create a new building model
78
Model model;
79
80
// Get or create the building object
81
Building building = model.getUniqueModelObject<Building>();
82
building.setName("Sample Building");
83
84
// Create a thermal zone
85
Zone zone(model);
86
zone.setName("Main Zone");
87
88
// Translate to EnergyPlus
89
energyplus::ForwardTranslator ft;
90
Workspace workspace = ft.translateModel(model);
91
92
// Save to IDF file
93
workspace.save(Path("building.idf"), true);
94
```
95
96
## Architecture
97
98
OpenStudio is built around several key components:
99
100
- **Model Framework**: Object-oriented representation of building components using template-based type-safe access
101
- **Translation Layer**: Bidirectional conversion between OpenStudio models and EnergyPlus IDF format
102
- **Measure System**: Parametric analysis framework for automated model modifications
103
- **Workflow Engine**: Orchestrates complete building simulation workflows from model to results
104
- **Utility Infrastructure**: Comprehensive support for geometry, units, file I/O, and data structures
105
- **Language Bindings**: SWIG-generated bindings for Ruby, Python, C#, and JavaScript
106
107
## Capabilities
108
109
### Building Model Management
110
111
Core classes for creating and managing building energy models with hierarchical object relationships and template-based type safety.
112
113
```python { .api }
114
# Python API
115
class Model:
116
def __init__(self)
117
118
# Object access methods
119
def getModelObject(self, handle): # Returns optional object
120
def getConcreteModelObjects(self, object_type): # Returns list
121
def getUniqueModelObject(self, object_type): # Returns single object
122
123
# Model operations
124
def sqlFile(self): # Returns optional SqlFile
125
def setSqlFile(self, sql_file): # Returns bool
126
def insertComponent(self, component): # Returns ComponentData
127
128
# HVAC operations
129
def connect(self, source_object, source_port, target_object, target_port): # Returns bool
130
131
class ModelObject:
132
def clone(self, model): # Returns ModelObject
133
def createComponent(self): # Returns Component
134
def model(self): # Returns Model
135
136
def resources(self): # Returns list of ResourceObject
137
def outputVariables(self): # Returns list of OutputVariable
138
def lifeCycleCosts(self): # Returns list of LifeCycleCost
139
```
140
141
```cpp { .api }
142
// C++ API
143
class Model : public openstudio::Workspace {
144
public:
145
// Template-based object access
146
template<typename T>
147
boost::optional<T> getModelObject(const Handle& handle) const;
148
149
template<typename T>
150
std::vector<T> getConcreteModelObjects() const;
151
152
template<typename T>
153
T getUniqueModelObject();
154
155
// Model operations
156
boost::optional<SqlFile> sqlFile() const;
157
bool setSqlFile(const SqlFile& sqlFile);
158
ComponentData insertComponent(const Component& component);
159
160
// HVAC operations
161
bool connect(ModelObject sourceObject,
162
unsigned sourcePort,
163
ModelObject targetObject,
164
unsigned targetPort);
165
};
166
167
class ModelObject : public openstudio::WorkspaceObject {
168
public:
169
ModelObject clone(Model model) const;
170
Component createComponent() const;
171
Model model() const;
172
173
std::vector<ResourceObject> resources() const;
174
std::vector<OutputVariable> outputVariables() const;
175
std::vector<LifeCycleCost> lifeCycleCosts() const;
176
};
177
```
178
179
[Building Model Classes](./model.md)
180
181
### Utility Infrastructure
182
183
Comprehensive utility classes for geometry, units, file I/O, and data structures that form the foundation of the OpenStudio SDK.
184
185
```python { .api }
186
# Python API
187
class Path:
188
def __init__(self)
189
def __init__(self, path_string)
190
191
def string(self): # Returns str
192
def filename(self): # Returns str
193
def stem(self): # Returns str
194
def extension(self): # Returns str
195
196
def exists(self): # Returns bool
197
def is_complete(self): # Returns bool
198
def empty(self): # Returns bool
199
200
class Point3d:
201
def __init__(self)
202
def __init__(self, x, y, z)
203
204
def x(self): # Returns float
205
def y(self): # Returns float
206
def z(self): # Returns float
207
208
def __sub__(self, other): # Returns Vector3d
209
def __add__(self, vec): # Returns Point3d
210
211
class Quantity:
212
def __init__(self)
213
def __init__(self, value, units)
214
215
def value(self): # Returns float
216
def units(self): # Returns Unit
217
218
def convert(self, target_units): # Returns optional Quantity
219
```
220
221
```cpp { .api }
222
// C++ API
223
class Path {
224
public:
225
Path();
226
Path(const std::string& p);
227
228
std::string string() const;
229
std::string filename() const;
230
std::string stem() const;
231
std::string extension() const;
232
233
bool exists() const;
234
bool is_complete() const;
235
bool empty() const;
236
};
237
238
class Point3d {
239
public:
240
Point3d();
241
Point3d(double x, double y, double z);
242
243
double x() const;
244
double y() const;
245
double z() const;
246
247
Vector3d operator-(const Point3d& other) const;
248
Point3d operator+(const Vector3d& vec) const;
249
};
250
251
class Quantity {
252
public:
253
Quantity();
254
Quantity(double value, const Unit& units);
255
256
double value() const;
257
Unit units() const;
258
259
boost::optional<Quantity> convert(const Unit& targetUnits) const;
260
};
261
```
262
263
[Utility Classes](./utilities.md)
264
265
### EnergyPlus Integration
266
267
Translation between OpenStudio models and EnergyPlus IDF format for building energy simulation.
268
269
```python { .api }
270
# Python API
271
class ForwardTranslator:
272
def __init__(self)
273
274
def translateModel(self, model): # Returns Workspace
275
276
def warnings(self): # Returns list of LogMessage
277
def errors(self): # Returns list of LogMessage
278
279
class ReverseTranslator:
280
def __init__(self)
281
282
def translateWorkspace(self, workspace): # Returns optional Model
283
284
def warnings(self): # Returns list of LogMessage
285
def errors(self): # Returns list of LogMessage
286
```
287
288
```cpp { .api }
289
// C++ API
290
class ForwardTranslator {
291
public:
292
ForwardTranslator();
293
294
Workspace translateModel(const Model& model);
295
296
std::vector<LogMessage> warnings() const;
297
std::vector<LogMessage> errors() const;
298
};
299
300
class ReverseTranslator {
301
public:
302
ReverseTranslator();
303
304
boost::optional<Model> translateWorkspace(const Workspace& workspace);
305
306
std::vector<LogMessage> warnings() const;
307
std::vector<LogMessage> errors() const;
308
};
309
```
310
311
[EnergyPlus Integration](./energyplus.md)
312
313
### Measure Framework
314
315
Parametric analysis framework for automated model modifications and simulation workflows.
316
317
```python { .api }
318
# Python API
319
class OSMeasure:
320
def arguments(self): # Returns list of OSArgument
321
def run(self, model, runner, user_arguments): # Returns bool
322
323
class ModelMeasure(OSMeasure):
324
def run(self, model, runner, user_arguments): # Returns bool
325
326
class OSArgument:
327
@staticmethod
328
def makeBoolArgument(name): # Returns OSArgument
329
@staticmethod
330
def makeDoubleArgument(name): # Returns OSArgument
331
@staticmethod
332
def makeStringArgument(name): # Returns OSArgument
333
@staticmethod
334
def makeChoiceArgument(name, choices): # Returns OSArgument
335
```
336
337
```cpp { .api }
338
// C++ API
339
class OSMeasure {
340
public:
341
virtual ~OSMeasure() = default;
342
343
virtual OSArgumentVector arguments() = 0;
344
virtual bool run(Model& model,
345
OSRunner& runner,
346
const OSArgumentMap& user_arguments) = 0;
347
};
348
349
class ModelMeasure : public OSMeasure {
350
public:
351
virtual bool run(Model& model,
352
OSRunner& runner,
353
const OSArgumentMap& user_arguments) override = 0;
354
};
355
356
class OSArgument {
357
public:
358
static OSArgument makeBoolArgument(const std::string& name);
359
static OSArgument makeDoubleArgument(const std::string& name);
360
static OSArgument makeStringArgument(const std::string& name);
361
static OSArgument makeChoiceArgument(const std::string& name,
362
const StringVector& choices);
363
};
364
```
365
366
[Measure Framework](./measure.md)
367
368
### Workflow Management
369
370
Orchestration of complete building simulation workflows from initial model through results processing.
371
372
```python { .api }
373
# Python API
374
class OSWorkflow:
375
def __init__(self)
376
def __init__(self, osw_path)
377
378
def run(self): # Returns bool
379
380
def model(self): # Returns optional Model
381
def workspace(self): # Returns optional Workspace
382
def sqlFile(self): # Returns optional SqlFile
383
384
def errors(self): # Returns list of LogMessage
385
def warnings(self): # Returns list of LogMessage
386
387
class WorkflowStepType:
388
ModelMeasure = "ModelMeasure"
389
EnergyPlusMeasure = "EnergyPlusMeasure"
390
ReportingMeasure = "ReportingMeasure"
391
392
class WorkflowStep:
393
def type(self): # Returns WorkflowStepType
394
def measure(self): # Returns optional BCLMeasure
395
def arguments(self): # Returns dict
396
```
397
398
```cpp { .api }
399
// C++ API
400
class OSWorkflow {
401
public:
402
OSWorkflow();
403
explicit OSWorkflow(const Path& oswPath);
404
405
bool run();
406
407
boost::optional<Model> model() const;
408
boost::optional<Workspace> workspace() const;
409
boost::optional<SqlFile> sqlFile() const;
410
411
std::vector<LogMessage> errors() const;
412
std::vector<LogMessage> warnings() const;
413
};
414
415
enum class WorkflowStepType {
416
ModelMeasure,
417
EnergyPlusMeasure,
418
ReportingMeasure
419
};
420
421
class WorkflowStep {
422
public:
423
WorkflowStepType type() const;
424
boost::optional<BCLMeasure> measure() const;
425
OSArgumentMap arguments() const;
426
};
427
```
428
429
[Workflow Management](./workflow.md)
430
431
### Daylight Analysis
432
433
Integration with Radiance for advanced daylight and lighting analysis capabilities.
434
435
```python { .api }
436
# Python API - openstudio.radiance module
437
class ForwardTranslator:
438
def __init__(self)
439
440
def translateModel(self, out_path, model): # Returns list of Path
441
442
def translateSpace(self, out_path, space): # Returns bool
443
444
class AnnualIlluminanceMap:
445
def __init__(self, path)
446
447
def illuminanceMap(self): # Returns optional Matrix
448
def dateTimes(self): # Returns list of DateTime
449
def values(self): # Returns list of float
450
```
451
452
```cpp { .api }
453
// C++ API
454
namespace radiance {
455
456
class ForwardTranslator {
457
public:
458
ForwardTranslator();
459
460
std::vector<Path> translateModel(const Path& outPath,
461
const Model& model);
462
463
bool translateSpace(const Path& outPath,
464
const Space& space);
465
};
466
467
class AnnualIlluminanceMap {
468
public:
469
AnnualIlluminanceMap(const Path& path);
470
471
boost::optional<Matrix> illuminanceMap() const;
472
std::vector<DateTime> dateTimes() const;
473
std::vector<double> values() const;
474
};
475
476
}
477
```
478
479
[Daylight Analysis](./radiance.md)
480
481
## Common Usage Patterns
482
483
### Object Access Patterns
484
485
**Python (Pythonic API):**
486
```python
487
# Get specific object types
488
zones = model.getConcreteModelObjects(model.Zone)
489
building = model.getOptionalUniqueModelObject(model.Building)
490
491
# Access by handle
492
zone_handle = zones[0].handle()
493
zone = model.getModelObject(zone_handle)
494
```
495
496
**C++ (Template-Based Access):**
497
```cpp
498
// Get specific object types
499
std::vector<Zone> zones = model.getConcreteModelObjects<Zone>();
500
boost::optional<Building> building = model.getOptionalUniqueModelObject<Building>();
501
502
// Safe casting with handle
503
Handle zoneHandle = zones[0].handle();
504
boost::optional<Zone> zone = model.getModelObject<Zone>(zoneHandle);
505
```
506
507
### Object Relationships
508
509
Building objects maintain parent-child and usage relationships:
510
511
**Python:**
512
```python
513
# Parent-child hierarchy
514
space = surface.space()
515
if space:
516
surfaces = space.surfaces()
517
zone = space.thermalZone()
518
519
# Resource usage
520
construction = model.Construction(model)
521
users = construction.getModelObjectSources()
522
resources = surface.resources()
523
```
524
525
**C++:**
526
```cpp
527
// Parent-child hierarchy
528
boost::optional<Space> space = surface.space();
529
if (space) {
530
std::vector<Surface> surfaces = space->surfaces();
531
boost::optional<ThermalZone> zone = space->thermalZone();
532
}
533
534
// Resource usage
535
Construction construction(model);
536
std::vector<ModelObject> users = construction.getModelObjectSources<>();
537
std::vector<ResourceObject> resources = surface.resources();
538
```
539
540
### Memory Management
541
542
**Python (Automatic Garbage Collection):**
543
```python
544
# Python handles memory management automatically
545
model = model.Model()
546
zone = model.Zone(model)
547
548
# Objects are garbage collected when no longer referenced
549
# No explicit cleanup needed
550
```
551
552
**C++ (RAII Principles):**
553
```cpp
554
{
555
Model model; // Automatic cleanup when scope ends
556
Zone zone(model); // Objects manage their own lifecycle
557
558
// No explicit cleanup needed
559
} // All objects automatically cleaned up here
560
```