fairyfly-therm 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fairyfly_therm/__init__.py +8 -0
- fairyfly_therm/__main__.py +4 -0
- fairyfly_therm/cli/__init__.py +47 -0
- fairyfly_therm/cli/setconfig.py +75 -0
- fairyfly_therm/condition/__init__.py +1 -0
- fairyfly_therm/condition/_base.py +167 -0
- fairyfly_therm/condition/comprehensive.py +412 -0
- fairyfly_therm/config.json +6 -0
- fairyfly_therm/config.py +315 -0
- fairyfly_therm/lib/__init__.py +1 -0
- fairyfly_therm/lib/_loadconditions.py +87 -0
- fairyfly_therm/lib/_loadgases.py +98 -0
- fairyfly_therm/lib/_loadmaterials.py +98 -0
- fairyfly_therm/lib/conditions.py +24 -0
- fairyfly_therm/lib/gases.py +36 -0
- fairyfly_therm/lib/materials.py +38 -0
- fairyfly_therm/material/__init__.py +1 -0
- fairyfly_therm/material/_base.py +182 -0
- fairyfly_therm/material/cavity.py +377 -0
- fairyfly_therm/material/gas.py +925 -0
- fairyfly_therm/material/solid.py +399 -0
- fairyfly_therm/material/xmlutil.py +45 -0
- fairyfly_therm-0.3.1.dist-info/METADATA +86 -0
- fairyfly_therm-0.3.1.dist-info/RECORD +28 -0
- fairyfly_therm-0.3.1.dist-info/WHEEL +5 -0
- fairyfly_therm-0.3.1.dist-info/entry_points.txt +2 -0
- fairyfly_therm-0.3.1.dist-info/licenses/LICENSE +661 -0
- fairyfly_therm-0.3.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""fairyfly-radiance library."""
|
|
2
|
+
|
|
3
|
+
from fairyfly.logutil import get_logger
|
|
4
|
+
|
|
5
|
+
# use the same logger settings across fairyfly extensions
|
|
6
|
+
# this does NOT mean that the logs will be written to the same file but they will have
|
|
7
|
+
# the same formatting, level, etc.
|
|
8
|
+
logger = get_logger(name=__name__)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""fairyfly-therm commands which will be added to fairyfly command line interface."""
|
|
2
|
+
import click
|
|
3
|
+
import sys
|
|
4
|
+
import logging
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
from fairyfly.cli import main
|
|
8
|
+
from ..config import folders
|
|
9
|
+
from .setconfig import set_config
|
|
10
|
+
|
|
11
|
+
_logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# command group for all therm extension commands.
|
|
15
|
+
@click.group(help='fairyfly therm commands.')
|
|
16
|
+
@click.version_option()
|
|
17
|
+
def therm():
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@therm.command('config')
|
|
22
|
+
@click.option('--output-file', help='Optional file to output the JSON string of '
|
|
23
|
+
'the config object. By default, it will be printed out to stdout',
|
|
24
|
+
type=click.File('w'), default='-', show_default=True)
|
|
25
|
+
def config(output_file):
|
|
26
|
+
"""Get a JSON object with all configuration information"""
|
|
27
|
+
try:
|
|
28
|
+
config_dict = {
|
|
29
|
+
'therm_path': folders.therm_path,
|
|
30
|
+
'therm_version': folders.therm_version_str,
|
|
31
|
+
'lbnl_data_path': folders.lbnl_data_path,
|
|
32
|
+
'therm_settings_path': folders.therm_settings_path,
|
|
33
|
+
'therm_lib_path': folders.therm_lib_path
|
|
34
|
+
}
|
|
35
|
+
output_file.write(json.dumps(config_dict, indent=4))
|
|
36
|
+
except Exception as e:
|
|
37
|
+
_logger.exception('Failed to retrieve configurations.\n{}'.format(e))
|
|
38
|
+
sys.exit(1)
|
|
39
|
+
else:
|
|
40
|
+
sys.exit(0)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# add sub-commands to therm
|
|
44
|
+
therm.add_command(set_config, name='set-config')
|
|
45
|
+
|
|
46
|
+
# add therm sub-commands to fairyfly CLI
|
|
47
|
+
main.add_command(therm)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Commands to set fairyfly-therm configurations."""
|
|
2
|
+
import click
|
|
3
|
+
import sys
|
|
4
|
+
import logging
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
from fairyfly_therm.config import folders
|
|
8
|
+
|
|
9
|
+
_logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@click.group(help='Commands to set fairyfly-therm configurations.')
|
|
13
|
+
def set_config():
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@set_config.command('therm-path')
|
|
18
|
+
@click.argument('folder-path', required=False, type=click.Path(
|
|
19
|
+
exists=True, file_okay=False, dir_okay=True, resolve_path=True))
|
|
20
|
+
def therm_path(folder_path):
|
|
21
|
+
"""Set the therm-path configuration variable.
|
|
22
|
+
|
|
23
|
+
\b
|
|
24
|
+
Args:
|
|
25
|
+
folder_path: Path to a folder to be set as the therm-path.
|
|
26
|
+
If unspecified, the therm-path will be set back to the default.
|
|
27
|
+
"""
|
|
28
|
+
_set_config_variable(folder_path, 'therm_path')
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@set_config.command('lbnl-data-path')
|
|
32
|
+
@click.argument('folder-path', required=False, type=click.Path(
|
|
33
|
+
exists=True, file_okay=False, dir_okay=True, resolve_path=True))
|
|
34
|
+
def lbnl_data_path(folder_path):
|
|
35
|
+
"""Set the lbnl-data-path configuration variable.
|
|
36
|
+
|
|
37
|
+
\b
|
|
38
|
+
Args:
|
|
39
|
+
folder_path: Path to a folder to be set as the lbnl-data-path.
|
|
40
|
+
If unspecified, the lbnl-data-path will be set back to the default.
|
|
41
|
+
"""
|
|
42
|
+
_set_config_variable(folder_path, 'lbnl_data_path')
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@set_config.command('therm-lib-path')
|
|
46
|
+
@click.argument('folder-path', required=False, type=click.Path(
|
|
47
|
+
exists=True, file_okay=False, dir_okay=True, resolve_path=True))
|
|
48
|
+
def therm_lib_path(folder_path):
|
|
49
|
+
"""Set the therm-lib-path configuration variable.
|
|
50
|
+
|
|
51
|
+
\b
|
|
52
|
+
Args:
|
|
53
|
+
folder_path: Path to a folder to be set as the therm-lib-path.
|
|
54
|
+
If unspecified, the therm-lib-path will be set back to the default.
|
|
55
|
+
"""
|
|
56
|
+
_set_config_variable(folder_path, 'therm_lib_path')
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _set_config_variable(folder_path, variable_name):
|
|
60
|
+
var_cli_name = variable_name.replace('_', '-')
|
|
61
|
+
try:
|
|
62
|
+
config_file = folders.config_file
|
|
63
|
+
with open(config_file) as inf:
|
|
64
|
+
data = json.load(inf)
|
|
65
|
+
data[variable_name] = folder_path if folder_path is not None else ''
|
|
66
|
+
with open(config_file, 'w') as fp:
|
|
67
|
+
json.dump(data, fp, indent=4)
|
|
68
|
+
msg_end = 'reset to default' if folder_path is None \
|
|
69
|
+
else 'set to: {}'.format(folder_path)
|
|
70
|
+
print('{} successfully {}.'.format(var_cli_name, msg_end))
|
|
71
|
+
except Exception as e:
|
|
72
|
+
_logger.exception('Failed to set {}.\n{}'.format(var_cli_name, e))
|
|
73
|
+
sys.exit(1)
|
|
74
|
+
else:
|
|
75
|
+
sys.exit(0)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""fairyfly-therm conditions."""
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Base therm condition."""
|
|
3
|
+
from __future__ import division
|
|
4
|
+
import uuid
|
|
5
|
+
import random
|
|
6
|
+
|
|
7
|
+
from ladybug.color import Color
|
|
8
|
+
from fairyfly._lockable import lockable
|
|
9
|
+
from fairyfly.typing import valid_uuid
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@lockable
|
|
13
|
+
class _ThermConditionBase(object):
|
|
14
|
+
"""Base therm condition.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
identifier: Text string for a unique Condition ID. Must be < 100 characters
|
|
18
|
+
and not contain any thermPlus special characters. This will be used to
|
|
19
|
+
identify the object across a model and in the exported IDF.
|
|
20
|
+
|
|
21
|
+
Properties:
|
|
22
|
+
* identifier
|
|
23
|
+
* display_name
|
|
24
|
+
* color
|
|
25
|
+
* protected
|
|
26
|
+
* project_tag
|
|
27
|
+
* user_data
|
|
28
|
+
"""
|
|
29
|
+
__slots__ = ('_identifier', '_display_name', '_color', '_protected', '_project_tag',
|
|
30
|
+
'_user_data', '_locked')
|
|
31
|
+
|
|
32
|
+
def __init__(self, identifier):
|
|
33
|
+
"""Initialize therm condition base."""
|
|
34
|
+
self._locked = False
|
|
35
|
+
self.identifier = identifier
|
|
36
|
+
self._display_name = None
|
|
37
|
+
self.color = None
|
|
38
|
+
self.protected = False
|
|
39
|
+
self.project_tag = None
|
|
40
|
+
self._user_data = None
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def identifier(self):
|
|
44
|
+
"""Get or set a text string for the unique object identifier.
|
|
45
|
+
|
|
46
|
+
This must be a UUID in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
47
|
+
and it remains constant as the object is mutated, copied, and
|
|
48
|
+
serialized to different formats (eg. therm XML). As such, this
|
|
49
|
+
property is used to reference the object across a Model.
|
|
50
|
+
"""
|
|
51
|
+
return self._identifier
|
|
52
|
+
|
|
53
|
+
@identifier.setter
|
|
54
|
+
def identifier(self, value):
|
|
55
|
+
if value is None:
|
|
56
|
+
self._identifier = str(uuid.uuid4())
|
|
57
|
+
else:
|
|
58
|
+
self._identifier = valid_uuid(value, 'therm condition identifier')
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def display_name(self):
|
|
62
|
+
"""Get or set a string for the object name without any character restrictions.
|
|
63
|
+
|
|
64
|
+
If not set, this will be equal to the identifier.
|
|
65
|
+
"""
|
|
66
|
+
if self._display_name is None:
|
|
67
|
+
return self._identifier
|
|
68
|
+
return self._display_name
|
|
69
|
+
|
|
70
|
+
@display_name.setter
|
|
71
|
+
def display_name(self, value):
|
|
72
|
+
if value is not None:
|
|
73
|
+
try:
|
|
74
|
+
value = str(value)
|
|
75
|
+
except UnicodeEncodeError: # Python 2 machine lacking the character set
|
|
76
|
+
pass # keep it as unicode
|
|
77
|
+
self._display_name = value
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def color(self):
|
|
81
|
+
"""Get or set an optional color for the condition as it displays in THERM.
|
|
82
|
+
|
|
83
|
+
This will always be a Ladybug Color object when getting this property
|
|
84
|
+
but the setter supports specifying hex codes. If unspecified, a radom
|
|
85
|
+
color will automatically be assigned.
|
|
86
|
+
"""
|
|
87
|
+
return self._color
|
|
88
|
+
|
|
89
|
+
@color.setter
|
|
90
|
+
def color(self, value):
|
|
91
|
+
if value is None:
|
|
92
|
+
self._color = Color(
|
|
93
|
+
random.randint(0, 255),
|
|
94
|
+
random.randint(0, 255),
|
|
95
|
+
random.randint(0, 255)
|
|
96
|
+
)
|
|
97
|
+
elif isinstance(value, str):
|
|
98
|
+
value = value.replace('0x', '')
|
|
99
|
+
self._color = Color.from_hex(value)
|
|
100
|
+
else:
|
|
101
|
+
assert isinstance(value, Color), 'Expected ladybug Color object for ' \
|
|
102
|
+
'condition color. Got {}.'.format(type(value))
|
|
103
|
+
self._color = value
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def protected(self):
|
|
107
|
+
"""Get or set a boolean for whether the condition is protected in THERM."""
|
|
108
|
+
return self._protected
|
|
109
|
+
|
|
110
|
+
@protected.setter
|
|
111
|
+
def protected(self, value):
|
|
112
|
+
try:
|
|
113
|
+
self._protected = bool(value)
|
|
114
|
+
except TypeError:
|
|
115
|
+
raise TypeError(
|
|
116
|
+
'Expected boolean for Condition.protected. Got {}.'.format(value))
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def project_tag(self):
|
|
120
|
+
"""Get or set a string for the condition's project name."""
|
|
121
|
+
return self._project_tag
|
|
122
|
+
|
|
123
|
+
@project_tag.setter
|
|
124
|
+
def project_tag(self, value):
|
|
125
|
+
if value is not None:
|
|
126
|
+
try:
|
|
127
|
+
value = str(value)
|
|
128
|
+
except UnicodeEncodeError: # Python 2 machine lacking the character set
|
|
129
|
+
pass # keep it as unicode
|
|
130
|
+
self._project_tag = value
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def user_data(self):
|
|
134
|
+
"""Get or set an optional dictionary for additional meta data for this object.
|
|
135
|
+
|
|
136
|
+
This will be None until it has been set. All keys and values of this
|
|
137
|
+
dictionary should be of a standard Python type to ensure correct
|
|
138
|
+
serialization of the object to/from JSON (eg. str, float, int, list, dict)
|
|
139
|
+
"""
|
|
140
|
+
if self._user_data is not None:
|
|
141
|
+
return self._user_data
|
|
142
|
+
|
|
143
|
+
@user_data.setter
|
|
144
|
+
def user_data(self, value):
|
|
145
|
+
if value is not None:
|
|
146
|
+
assert isinstance(value, dict), 'Expected dictionary for fairyfly_therm' \
|
|
147
|
+
'object user_data. Got {}.'.format(type(value))
|
|
148
|
+
self._user_data = value
|
|
149
|
+
|
|
150
|
+
def duplicate(self):
|
|
151
|
+
"""Get a copy of this construction."""
|
|
152
|
+
return self.__copy__()
|
|
153
|
+
|
|
154
|
+
def __copy__(self):
|
|
155
|
+
new_obj = self.__class__(self.identifier)
|
|
156
|
+
new_obj._display_name = self._display_name
|
|
157
|
+
new_obj._color = self._color
|
|
158
|
+
new_obj._project_tag = self._project_tag
|
|
159
|
+
new_obj._user_data = None if self._user_data is None else self._user_data.copy()
|
|
160
|
+
return new_obj
|
|
161
|
+
|
|
162
|
+
def ToString(self):
|
|
163
|
+
"""Overwrite .NET ToString."""
|
|
164
|
+
return self.__repr__()
|
|
165
|
+
|
|
166
|
+
def __repr__(self):
|
|
167
|
+
return 'Base THERM Condition:\n{}'.format(self.display_name)
|