honeybee-core 1.64.12__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.
Files changed (48) hide show
  1. honeybee/__init__.py +23 -0
  2. honeybee/__main__.py +4 -0
  3. honeybee/_base.py +331 -0
  4. honeybee/_basewithshade.py +310 -0
  5. honeybee/_lockable.py +99 -0
  6. honeybee/altnumber.py +47 -0
  7. honeybee/aperture.py +997 -0
  8. honeybee/boundarycondition.py +358 -0
  9. honeybee/checkdup.py +173 -0
  10. honeybee/cli/__init__.py +118 -0
  11. honeybee/cli/compare.py +132 -0
  12. honeybee/cli/create.py +265 -0
  13. honeybee/cli/edit.py +559 -0
  14. honeybee/cli/lib.py +103 -0
  15. honeybee/cli/setconfig.py +43 -0
  16. honeybee/cli/validate.py +224 -0
  17. honeybee/colorobj.py +363 -0
  18. honeybee/config.json +5 -0
  19. honeybee/config.py +347 -0
  20. honeybee/dictutil.py +54 -0
  21. honeybee/door.py +746 -0
  22. honeybee/extensionutil.py +208 -0
  23. honeybee/face.py +2360 -0
  24. honeybee/facetype.py +153 -0
  25. honeybee/logutil.py +79 -0
  26. honeybee/model.py +4272 -0
  27. honeybee/orientation.py +132 -0
  28. honeybee/properties.py +845 -0
  29. honeybee/room.py +3485 -0
  30. honeybee/search.py +107 -0
  31. honeybee/shade.py +514 -0
  32. honeybee/shademesh.py +362 -0
  33. honeybee/typing.py +498 -0
  34. honeybee/units.py +88 -0
  35. honeybee/writer/__init__.py +7 -0
  36. honeybee/writer/aperture.py +6 -0
  37. honeybee/writer/door.py +6 -0
  38. honeybee/writer/face.py +6 -0
  39. honeybee/writer/model.py +6 -0
  40. honeybee/writer/room.py +6 -0
  41. honeybee/writer/shade.py +6 -0
  42. honeybee/writer/shademesh.py +6 -0
  43. honeybee_core-1.64.12.dist-info/METADATA +94 -0
  44. honeybee_core-1.64.12.dist-info/RECORD +48 -0
  45. honeybee_core-1.64.12.dist-info/WHEEL +5 -0
  46. honeybee_core-1.64.12.dist-info/entry_points.txt +2 -0
  47. honeybee_core-1.64.12.dist-info/licenses/LICENSE +661 -0
  48. honeybee_core-1.64.12.dist-info/top_level.txt +1 -0
honeybee/facetype.py ADDED
@@ -0,0 +1,153 @@
1
+ """Face Types."""
2
+ from ladybug_geometry.geometry3d.pointvector import Vector3D
3
+ import re
4
+ import math
5
+
6
+
7
+ class _FaceType(object):
8
+ __slots__ = ()
9
+
10
+ def __init__(self):
11
+ pass
12
+
13
+ @property
14
+ def name(self):
15
+ return self.__class__.__name__
16
+
17
+ def ToString(self):
18
+ return self.__repr__()
19
+
20
+ def __eq__(self, other):
21
+ return self.__class__ == other.__class__
22
+
23
+ def __ne__(self, other):
24
+ return not self.__eq__(other)
25
+
26
+ def __repr__(self):
27
+ return self.name
28
+
29
+
30
+ class Wall(_FaceType):
31
+ """Type for walls."""
32
+ __slots__ = ()
33
+ pass
34
+
35
+
36
+ class RoofCeiling(_FaceType):
37
+ """Type for roofs and ceilings."""
38
+ __slots__ = ()
39
+ pass
40
+
41
+
42
+ class Floor(_FaceType):
43
+ """Type for floors."""
44
+ __slots__ = ()
45
+ pass
46
+
47
+
48
+ class AirBoundary(_FaceType):
49
+ """Type for air boundaries (aka. virtual partitions) between Rooms."""
50
+ __slots__ = ()
51
+ pass
52
+
53
+
54
+ class _FaceTypes(object):
55
+ """Face types."""
56
+
57
+ def __init__(self):
58
+ self._wall = Wall()
59
+ self._roof_ceiling = RoofCeiling()
60
+ self._floor = Floor()
61
+ self._air_boundary = AirBoundary()
62
+ self._type_name_dict = None
63
+
64
+ @property
65
+ def wall(self):
66
+ return self._wall
67
+
68
+ @property
69
+ def roof_ceiling(self):
70
+ return self._roof_ceiling
71
+
72
+ @property
73
+ def floor(self):
74
+ return self._floor
75
+
76
+ @property
77
+ def air_boundary(self):
78
+ return self._air_boundary
79
+
80
+ def by_name(self, face_type_name):
81
+ """Get a Face Type instance from its name.
82
+
83
+ This method will correct for capitalization as well as the presence of
84
+ spaces and underscores.
85
+
86
+ Args:
87
+ face_type_name: A text string for the face type (eg. "Wall").
88
+ """
89
+ if self._type_name_dict is None:
90
+ self._build_type_name_dict()
91
+ try:
92
+ return self._type_name_dict[re.sub(r'[\s_]', '', face_type_name.lower())]
93
+ except KeyError:
94
+ raise ValueError(
95
+ '"{}" is not a valid face type name.\nChoose from the following'
96
+ ': {}'.format(face_type_name, list(self._type_name_dict.keys())))
97
+
98
+ def _build_type_name_dict(self):
99
+ """Build a dictionary that can be used to lookup face types by name."""
100
+ attr = [atr for atr in dir(self) if not atr.startswith('_')]
101
+ clean_attr = [re.sub(r'[\s_]', '', atr.lower()) for atr in attr]
102
+ self._type_name_dict = {}
103
+ for atr_name, atr in zip(clean_attr, attr):
104
+ try:
105
+ full_attr = getattr(self, '_' + atr)
106
+ self._type_name_dict[atr_name] = full_attr
107
+ except AttributeError:
108
+ pass # callable method that has no static default object
109
+
110
+ def __contains__(self, value):
111
+ return isinstance(value, _FaceType)
112
+
113
+ def __repr__(self):
114
+ attr = [atr for atr in dir(self) if not atr.startswith('_') and atr != 'by_name']
115
+ return 'Face Types:\n{}'.format('\n'.join(attr))
116
+
117
+
118
+ face_types = _FaceTypes()
119
+
120
+
121
+ def get_type_from_normal(normal_vector, roof_angle=60, floor_angle=130):
122
+ """Return face type based on the angle between Z axis and normal vector.
123
+
124
+ Angles between 0 and roof_angle will be set to roof_ceiling.
125
+ Angles between roof_angle and floor_angle will be set to wall.
126
+ Angles larger than floor angle will be set to floor.
127
+
128
+ Args:
129
+ normal_vector: Normal vector as a ladybug_geometry Vector3D.
130
+ roof_angle: A number between 0 and 90 to set the angle from the horizontal
131
+ plane below which faces will be considered roofs instead of
132
+ walls. 90 indicates that all vertical faces are roofs and 0
133
+ indicates that all horizontal faces are walls. (Default: 60,
134
+ recommended by the ASHRAE 90.1 standard).
135
+ floor_angle: A number between 90 and 180 to set the angle from the horizontal
136
+ plane above which faces will be considered floors instead of
137
+ walls. 180 indicates that all vertical faces are floors and 0
138
+ indicates that all horizontal faces are walls. (Default: 130,
139
+ recommended by the ASHRAE 90.1 standard).
140
+
141
+ Returns:
142
+ Face type instance.
143
+ """
144
+ z_axis = Vector3D(0, 0, 1)
145
+ angle = math.degrees(z_axis.angle(normal_vector))
146
+ if angle < roof_angle:
147
+ return face_types.roof_ceiling
148
+ elif roof_angle <= angle < floor_angle:
149
+ return face_types.wall
150
+ else:
151
+ return face_types.floor
152
+
153
+ return face_types.wall
honeybee/logutil.py ADDED
@@ -0,0 +1,79 @@
1
+ import logging
2
+ from logging.handlers import TimedRotatingFileHandler
3
+ import os
4
+ import tempfile
5
+
6
+
7
+ # This is copied from logging module since python 2 doesn't have it under the same name.
8
+ CRITICAL = 50
9
+ FATAL = CRITICAL
10
+ ERROR = 40
11
+ WARNING = 30
12
+ WARN = WARNING
13
+ INFO = 20
14
+ DEBUG = 10
15
+ NOTSET = 0
16
+
17
+ _name_to_level = {
18
+ 'CRITICAL': CRITICAL,
19
+ 'FATAL': FATAL,
20
+ 'ERROR': ERROR,
21
+ 'WARN': WARNING,
22
+ 'WARNING': WARNING,
23
+ 'INFO': INFO,
24
+ 'DEBUG': DEBUG,
25
+ 'NOTSET': NOTSET,
26
+ }
27
+
28
+
29
+ def _get_log_folder():
30
+ home_folder = os.getenv('HOME') or os.path.expanduser('~')
31
+ if not os.access(home_folder, os.W_OK):
32
+ home_folder = tempfile.gettempdir()
33
+ log_folder = os.path.join(home_folder, '.honeybee')
34
+ if not os.path.isdir(log_folder):
35
+ try:
36
+ os.mkdir(log_folder)
37
+ except OSError as e:
38
+ if e.errno != 17: # avoid race conditions between multiple tasks
39
+ raise OSError('Failed to create log folder: %s\n%s' % (log_folder, e))
40
+ return log_folder
41
+
42
+
43
+ def _get_log_level(level):
44
+ level = _name_to_level.get(level)
45
+ return level or logging.INFO
46
+
47
+
48
+ def get_logger(name, filename='honeybee.log', file_log_level='DEBUG',
49
+ console_log_level='WARNING'):
50
+ """Get a logger to be used for each module.
51
+
52
+ Args:
53
+ name: Logger name. The good practice is to set it to __init__ from inside each
54
+ modules.
55
+ filename: Logger filename.Setting filename to None will remove the file handler
56
+ (Default: honeybee.log).
57
+ file_log_level: Log level for file handler as a string (Default: DEBUG).
58
+ console_log_level: Log level for stream handler as a string (Default: WARNING).
59
+ """
60
+ logger = logging.getLogger(name)
61
+
62
+ # create a file handler to log debug and higher level logs
63
+ if filename:
64
+ log_file = os.path.join(_get_log_folder(), filename)
65
+ file_handler = TimedRotatingFileHandler(log_file, when='midnight')
66
+ file_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
67
+ file_handler.setFormatter(file_format)
68
+ file_handler.setLevel(_get_log_level(file_log_level))
69
+ logger.addHandler(file_handler)
70
+
71
+ # create a console handler that only prints out errors and warnings
72
+ stream_handler = logging.StreamHandler()
73
+ stream_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
74
+ stream_handler.setFormatter(stream_format)
75
+ stream_handler.setLevel(_get_log_level(console_log_level))
76
+
77
+ logger.addHandler(stream_handler)
78
+
79
+ return logger