Skip to content

Commit

Permalink
feat(serialize): Include version check and use .dfjson file extension
Browse files Browse the repository at this point in the history
This commit includes 3 upgrades:
* Ensuring all of the Radiance object dictionaries can be re-serialized to Python from the plugins.
* Adding checks for the "version" key that we write into the Model JSONs and giving users a warning if the version does not match their installation.
* Making the file dfjson extension shift.
  • Loading branch information
chriswmackey authored and Chris Mackey committed Aug 13, 2020
1 parent 2ef573c commit 9a37e39
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 26 deletions.
13 changes: 3 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ following repositories to be installed in order to work correctly:

## Installation

To install the most recent version of the Grasshopper plugin, follow these steps:

1. Clone this repository to your machine.
2. Make sure you are connected to the internet and open the installer.gh file in Grasshopper.
3. Set the toggle inside the file to `True`.
4. Restart Rhino + Grasshopper.

Note that following these steps will install the absolute most recent version of
the plugin. To install the last stable release, download the components and Grasshopper
file installer from [food4rhino](https://www.food4rhino.com/app/ladybug-tools).
See the [Wiki of the lbt-grasshopper repository](https://github.com/ladybug-tools/lbt-grasshopper/wiki)
for the installation instructions for the entire Ladybug Tools Grasshopper plugin
(including this repository).
7 changes: 4 additions & 3 deletions dragonfly_grasshopper/src/DF Dump Objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

ghenv.Component.Name = 'DF Dump Objects'
ghenv.Component.NickName = 'DumpObjects'
ghenv.Component.Message = '0.1.0'
ghenv.Component.Message = '0.1.1'
ghenv.Component.Category = 'Dragonfly'
ghenv.Component.SubCategory = '2 :: Serialize'
ghenv.Component.AdditionalHelpFromDocStrings = '2'
Expand All @@ -50,7 +50,7 @@
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))

try: # import the core dragonfly dependencies
import dragonfly.model as Model
from dragonfly.model import Model
except ImportError as e:
raise ImportError('\nFailed to import dragonfly:\n\t{}'.format(e))

Expand All @@ -66,7 +66,8 @@
if all_required_inputs(ghenv.Component) and _dump:
# set the component defaults
name = _name_ if _name_ is not None else 'unnamed'
file_name = '{}.json'.format(name)
file_name = '{}.json'.format(name) if len(_df_objs) > 1 or not \
isinstance(_df_objs[0], Model) else '{}.dfjson'.format(name)
folder = _folder_ if _folder_ is not None else folders.default_simulation_folder
df_file = os.path.join(folder, file_name)
indent = indent_ if indent_ is not None else 0
Expand Down
55 changes: 44 additions & 11 deletions dragonfly_grasshopper/src/DF Load Objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,15 @@

ghenv.Component.Name = 'DF Load Objects'
ghenv.Component.NickName = 'LoadObjects'
ghenv.Component.Message = '0.1.1'
ghenv.Component.Message = '0.2.0'
ghenv.Component.Category = 'Dragonfly'
ghenv.Component.SubCategory = '2 :: Serialize'
ghenv.Component.AdditionalHelpFromDocStrings = '2'

try:
import honeybee.model as hb_model
except ImportError as e:
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))

try: # import the core dragonfly dependencies
import dragonfly.dictutil as df_dict_util
from dragonfly.model import Model
from dragonfly.config import folders
except ImportError as e:
raise ImportError('\nFailed to import dragonfly:\n\t{}'.format(e))

Expand All @@ -51,6 +47,11 @@
except ImportError as e:
raise ImportError('\nFailed to import honeybee_energy:\n\t{}'.format(e))

try: # import the core honeybee_radiance dependencies
import honeybee_radiance.dictutil as radiance_dict_util
except ImportError as e:
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))

try: # import the core ladybug_rhino dependencies
from ladybug_rhino.grasshopper import all_required_inputs, give_warning
from ladybug_rhino.config import units_system, tolerance
Expand Down Expand Up @@ -79,23 +80,55 @@ def model_units_tolerance_check(model):
'current Rhino model tolerance "{}".\nIt is recommended that the ' \
'Rhino document tolerance be changed to be coarser and this ' \
'component is re-reun.'.format(new_tol, tolerance)
give_warning(msg)
print msg
give_warning(ghenv.Component, msg)


def version_check(data):
"""Check the version of the object if it was included in the dictionary.
This is most useful in cases of importing entire Models to make sure
the Model isn't newer than the currently installed Dragonfly.
Args:
data: Dictionary of the object, which optionally has the "version" key.
"""
if 'version' in data and data['version'] is not None:
model_ver = tuple(int(d) for d in data['version'].split('.'))
df_ver = folders.dragonfly_schema_version
if model_ver > df_ver:
msg = 'Imported Model schema version "{}" is newer than that with the ' \
'currently installed Dragonfly "{}".\nThe Model may fail to import ' \
'or (worse) some newer features of the Model might not be imported ' \
'without detection.'.format(data['version'], folders.dragonfly_schema_version_str)
print msg
give_warning(ghenv.Component, msg)
elif model_ver != df_ver:
msg = 'Imported Model schema version "{}" is older than that with the ' \
'currently installed Dragonfly "{}".\nThe Model will be upgraded upon ' \
'import.'.format(data['version'], folders.dragonfly_schema_version_str)
print msg


if all_required_inputs(ghenv.Component) and _load:
with open(_df_file) as json_file:
data = json.load(json_file)

version_check(data) # try to check the version
try:
df_objs = df_dict_util.dict_to_object(data, False) # re-serialize as a core object
if df_objs is None: # try to re-serialize it as an energy object
df_objs = energy_dict_util.dict_to_object(hb_dict, False)
df_objs = energy_dict_util.dict_to_object(data, False)
if df_objs is None: # try to re-serialize it as a radiance object
df_objs = radiance_dict_util.dict_to_object(data, False)
elif isinstance(df_objs, Model):
model_units_tolerance_check(df_objs)
except ValueError: # no 'type' key; assume that its a group of objects
df_objs = []
for hb_dict in data.values():
df_obj = df_dict_util.dict_to_object(hb_dict, False) # re-serialize as a core object
for df_dict in data.values():
df_obj = df_dict_util.dict_to_object(df_dict, False) # re-serialize as a core object
if df_obj is None: # try to re-serialize it as an energy object
df_obj = energy_dict_util.dict_to_object(hb_dict, False)
df_obj = energy_dict_util.dict_to_object(df_dict, False)
if df_obj is None: # try to re-serialize it as a radiance object
df_obj = radiance_dict_util.dict_to_object(df_dict, False)
df_objs.append(df_obj)
66 changes: 64 additions & 2 deletions dragonfly_grasshopper/src/DF String to Object.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@

ghenv.Component.Name = 'DF String to Object'
ghenv.Component.NickName = 'StrToObj'
ghenv.Component.Message = '0.1.0'
ghenv.Component.Message = '0.2.0'
ghenv.Component.Category = 'Dragonfly'
ghenv.Component.SubCategory = '2 :: Serialize'
ghenv.Component.AdditionalHelpFromDocStrings = '1'

try: # import the core dragonfly dependencies
import dragonfly.dictutil as df_dict_util
from dragonfly.model import Model
from dragonfly.config import folders
except ImportError as e:
raise ImportError('\nFailed to import dragonfly:\n\t{}'.format(e))

Expand All @@ -41,16 +43,76 @@
except ImportError as e:
raise ImportError('\nFailed to import honeybee_energy:\n\t{}'.format(e))

try: # import the core honeybee_radiance dependencies
import honeybee_radiance.dictutil as radiance_dict_util
except ImportError as e:
raise ImportError('\nFailed to import honeybee_radiance:\n\t{}'.format(e))

try: # import the core ladybug_rhino dependencies
from ladybug_rhino.grasshopper import all_required_inputs
from ladybug_rhino.grasshopper import all_required_inputs, give_warning
from ladybug_rhino.config import units_system, tolerance
except ImportError as e:
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))

import json


def model_units_tolerance_check(model):
"""Convert a model to the current Rhino units and check the tolerance.
Args:
model: A honeybee Model, which will have its units checked.
"""
# check the model units
if model.units != units_system():
print('Imported model units "{}" do not match that of the current Rhino '
'model units "{}"\nThe model is being automatically converted '
'to the Rhino doc units.'.format(model.units, units_system()))
model.convert_to_units(units_system())

# check that the model tolerance is not too far from the Rhino tolerance
if model.tolerance / tolerance >= 100:
msg = 'Imported Model tolerance "{}" is significantly coarser than the ' \
'current Rhino model tolerance "{}".\nIt is recommended that the ' \
'Rhino document tolerance be changed to be coarser and this ' \
'component is re-run.'.format(new_tol, tolerance)
print msg
give_warning(ghenv.Component, msg)


def version_check(data):
"""Check the version of the object if it was included in the dictionary.
This is most useful in cases of importing entire Models to make sure
the Model isn't newer than the currently installed Dragonfly.
Args:
data: Dictionary of the object, which optionally has the "version" key.
"""
if 'version' in data and data['version'] is not None:
model_ver = tuple(int(d) for d in data['version'].split('.'))
df_ver = folders.dragonfly_schema_version
if model_ver > df_ver:
msg = 'Imported Model schema version "{}" is newer than that with the ' \
'currently installed Dragonfly "{}".\nThe Model may fail to import ' \
'or (worse) some newer features of the Model might not be imported ' \
'without detection.'.format(data['version'], folders.dragonfly_schema_version_str)
print msg
give_warning(ghenv.Component, msg)
elif model_ver != df_ver:
msg = 'Imported Model schema version "{}" is older than that with the ' \
'currently installed Dragonfly "{}".\nThe Model will be upgraded upon ' \
'import.'.format(data['version'], folders.dragonfly_schema_version_str)
print msg


if all_required_inputs(ghenv.Component):
df_dict = json.loads(_df_str)
version_check(df_dict) # try to check the version
df_obj = df_dict_util.dict_to_object(df_dict, False) # re-serialize as a core object
if df_obj is None: # try to re-serialize it as an energy object
df_obj = energy_dict_util.dict_to_object(df_dict, False)
if df_obj is None: # try to re-serialize it as a radiance object
df_obj = radiance_dict_util.dict_to_object(df_dict, False)
elif isinstance(df_obj, Model):
model_units_tolerance_check(df_obj)
Binary file modified dragonfly_grasshopper/user_objects/DF Dump Objects.ghuser
Binary file not shown.
Binary file modified dragonfly_grasshopper/user_objects/DF Load Objects.ghuser
Binary file not shown.
Binary file modified dragonfly_grasshopper/user_objects/DF String to Object.ghuser
Binary file not shown.
Binary file modified samples/rooms_to_stories_to_building.gh
Binary file not shown.

0 comments on commit 9a37e39

Please sign in to comment.