Skip to content

Commit

Permalink
Merge pull request #692 from architecture-building-systems/686-migrat…
Browse files Browse the repository at this point in the history
…e-combustion

Migrate EPW-reader and combustion from Hive.Core to Hive.IO
  • Loading branch information
maxenceryan authored Dec 22, 2021
2 parents 7a15263 + a9e20ed commit ce83574
Show file tree
Hide file tree
Showing 50 changed files with 1,729 additions and 634 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified GrasshopperExamples/LectureExercises/EaCS3_E04_Hive_Template.gh
Binary file not shown.
Binary file not shown.
Binary file modified GrasshopperExamples/LectureExercises/EaCS3_E0X_WalkieTalkie.gh
Binary file not shown.
Binary file not shown.
Binary file modified GrasshopperExamples/LectureExercises/EuKS2_02_Hive_Solar.gh
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified GrasshopperExamples/Testing/Hive_ConversionTech_Test.gh
Binary file not shown.
Binary file modified GrasshopperExamples/Testing/Hive_Distributor_Test.gh
Binary file not shown.
Binary file modified GrasshopperExamples/Testing/Hive_Environment_Test.gh
Binary file not shown.
Binary file modified GrasshopperExamples/Testing/Hive_Form_Building_Test.gh
Binary file not shown.
Binary file modified GrasshopperExamples/Testing/Hive_Form_PV.gh
Binary file not shown.
Binary file modified GrasshopperExamples/Testing/Hive_Results_Visualizer_Test.gh
Binary file not shown.
Binary file modified setup/Setup_Hive.exe
Binary file not shown.
4 changes: 2 additions & 2 deletions setup/build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ cd %HIVE_DIR%\src\Hive.Core\
"%IPY%" "%HB%" sia380\Hive.Core.sia380.json
"%IPY%" "%HB%" solar\Hive.Core.solar.json
"%IPY%" "%HB%" solar_tech\Hive.Core.solar_tech.json
"%IPY%" "%HB%" combustion\Hive.Core.combustion.json
@REM "%IPY%" "%HB%" combustion\Hive.Core.combustion.json
"%IPY%" "%HB%" cooling\Hive.Core.cooling.json
"%IPY%" "%HB%" heatpumps\Hive.Core.heatpumps.json
echo ...Done
Expand All @@ -52,7 +52,7 @@ cd %HIVE_DIR%\src\Hive.Core\
"%IPY%" "%HIVE_WIKI_PY%" sia380\Hive.Core.sia380.json
"%IPY%" "%HIVE_WIKI_PY%" solar\Hive.Core.solar.json
"%IPY%" "%HIVE_WIKI_PY%" solar_tech\Hive.Core.solar_tech.json
"%IPY%" "%HIVE_WIKI_PY%" combustion\Hive.Core.combustion.json
@REM "%IPY%" "%HIVE_WIKI_PY%" combustion\Hive.Core.combustion.json
"%IPY%" "%HIVE_WIKI_PY%" cooling\Hive.Core.cooling.json
"%IPY%" "%HIVE_WIKI_PY%" heatpumps\Hive.Core.heatpumps.json

Expand Down
2 changes: 1 addition & 1 deletion setup/hive.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Section "Base Installation" Base_Installation_Section
File "..\src\Hive.Core\solar\_build\Hive.Core.solar.ghpy"
File "..\src\Hive.Core\solar_tech\_build\Hive.Core.solar_tech.ghpy"
File "..\src\Hive.Core\solar_tech\_build\Hive.Core.solar_tech.gha"
File "..\src\Hive.Core\combustion\_build\Hive.Core.combustion.ghpy"
; File "..\src\Hive.Core\combustion\_build\Hive.Core.combustion.ghpy"
File "..\src\Hive.Core\cooling\_build\Hive.Core.cooling.ghpy"
File "..\src\Hive.Core\heatpumps\_build\Hive.Core.heatpumps.ghpy"

Expand Down
290 changes: 290 additions & 0 deletions src/Hive.Core/migration-script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
import json
import os
import string
from mako.template import Template


def main(badger_file):

# parameter_compiler.setup(rhino_version)
# temporary create the helloworld dll adding the honey-badger.json to it
with open(badger_file, mode='r') as bf:
badger_file_contents = bf.read()
badger_config = json.loads(badger_file_contents)

badger_dir = os.path.abspath(os.path.dirname(badger_file))
build_dir = os.path.join(badger_dir, '_build')
if not os.path.exists(build_dir):
os.makedirs(build_dir)

badger_config = check_badger_config(badger_config, badger_dir)

from mako.exceptions import RichTraceback
for component in badger_config['components']:
component['class_name'] = component['class-name']
component['exposure'] = 'secondary'
inputs = RegisterInputParams(component)
outputs = RegisterOutputParams(component)
set_inputs = SolvePrefix(component)
set_outputs = SolveSuffix(component)

try:
mytemplate = Template(COMPONENT_TEMPLATE, strict_undefined=True, default_filters=['decode.utf8'], input_encoding='utf-8', output_encoding='utf-8')
text = mytemplate.render(register_inputs= inputs,
register_outputs = outputs,
set_inputs= set_inputs,
set_outputs= set_outputs,
solve_instance= SOLVE_INSTANCE,
**component
# id="",
# icon="",
# abbreviation="",
# description="",
# nick_name="",
# name="",
# category="",
# subcategory="",
# exposure="",
# class_name=""
)

filename = component['abbreviation'] + '.cs'
path = os.path.join(os.path.dirname(config_path), filename)
with open(path, 'w') as file:
file.write(text)
except:
traceback = RichTraceback()
for (filename, lineno, function, line) in traceback.traceback:
print("File %s, line %s, in %s" % (filename, lineno, function))
print(line, "\n")
print("%s: %s" % (str(traceback.error.__class__.__name__), traceback.error))


GH_PARAMETER_MAP = {
'arc': "Arc",
'boolean': "Boolean",
'box': "Box",
'brep': "Brep",
'circle': "Circle",
'colour': "Colour",
'complex': "Complex",
'culture': "Culture",
'curve': "Curve",
'field': "Field",
'filepath': "FilePath",
'generic': "GenericObject",
'geometry': "Geometry",
'group': "Group",
'guid': "Guid",
'integer': "Integer",
'interval': "Interval",
'interval2d': "Interval2D",
'latlonlocation': "LatLonLocation",
'line': "Line",
'matrix': "Matrix",
'mesh': "Mesh",
'meshface': "MeshFace",
'meshparameters': "MeshParameters",
'float': "Number",
'oglshader': "OGLShader",
'plane': "Plane",
'point': "Point",
'rectangle': "Rectangle",
'scriptvariable': "ScriptVariable",
'string': "Text",
'json': "String",
'structurepath': "StructurePath",
'surface': "Surface",
'time': "Time",
'transform': "Transform",
'vector': "Vector",
}

CS_TYPE_MAP = {
'float': 'double',
'string': 'string',
'integer': 'int',
'generic': 'object',
'json': 'Dictionary<string, object>',
'boolean': 'bool'
}

def RegisterInputParams(component):
text = []
for input in component['inputs']:
input['nickname'] = input['nick-name']
input['ghtype'] = GH_PARAMETER_MAP[input['type']]
text.append('pManager.Add{ghtype}Parameter("{name}", "{nickname}", "{description}", GH_ParamAccess.{access});' \
.format(**input))
return text

def RegisterOutputParams(component):
text = []
for output in component['outputs']:
output['nickname'] = output['nick-name']
output['ghtype'] = GH_PARAMETER_MAP[output['type']]
text.append('pManager.Add{ghtype}Parameter("{name}", "{nickname}", "{description}", GH_ParamAccess.{access});' \
.format(**output))
return text

def SolvePrefix(component):
text = []
for i, input in enumerate(component['inputs']):
input['cstype'] = CS_TYPE_MAP[input['type']]
if input['access'] == 'list':
input['list'] = 'List'
input['cstype'] = 'List<' + input['cstype'] + '>'
else :
input['list'] = ''

if input['default'] is None:
template = u"{cstype} {name} = new {cstype}();\n\t\t\tif (!DA.GetData{list}({index}, ref {name})) return;"
else:
template = u"{cstype} {name} = DA.GetData{list}({index}, ref {name}) ?? {default};"
text.append(template.format(index=i, **input))

text.append('\n')

for i, output in enumerate(component['outputs']):
output['cstype'] = CS_TYPE_MAP[output['type']]
if output['access'] == 'list':
output['list'] = 'List'
output['cstype'] = 'List<' + input['cstype'] + '>'
else :
output['list'] = ''
template = u"var {name} = new {cstype}();"
text.append(template.format(index=i, **output))

return text

def SolveSuffix(component):
text = []
for i, output in enumerate(component['outputs']):
output['list'] = 'List' if output['access'] == 'list' else ''
template = u"DA.SetData{list}({index}, {name});"
text.append(template.format(index=i, **output))
return text

def check_badger_config(badger_config, badger_dir):
"""
Make sure the badger file contains all the required info. Fill in default values if they don't exist yet.
nick-names and defaults for inputs/outputs are added automatically.
FIXME: this could also be done with some kind of json schema thing. For now, this provides enough info.
"""
assert "name" in badger_config, "Badger file needs a name"
assert "description" in badger_config, "Badger file needs a description"
assert "version" in badger_config, "Badger file needs a version"
assert "author" in badger_config, "Badger file needs an author"
assert "id" in badger_config, "Badger file needs an id"
assert "include-files" in badger_config, "Badger file needs to specify include-files"
if not "include-install" in badger_config:
badger_config["include-install"] = []
assert "components" in badger_config, "Badger file needs to specify at least one component"
for component in badger_config["components"]:
assert "class-name" in component, "Component needs a class name"
assert "name" in component, "Component needs a name"
assert "abbreviation" in component, "Component needs an abbreviation"
assert "description" in component, "Component needs a description"
assert "category" in component, "Component needs a category"
assert "subcategory" in component, "Component needs a subcategory"
assert "id" in component, "Component needs an id"
assert "main-module" in component, "Component needs a main-module"
assert "inputs" in component, "Component needs inputs"
assert "outputs" in component, "Component needs outputs"
for input in component["inputs"]:
assert "type" in input, "Input needs a type"
assert "name" in input, "Input needs a name"
assert "description" in input, "Input needs a description"
if not "nick-name" in input:
input["nick-name"] = input["name"]
if not "default" in input:
input["default"] = None
if not "access" in input:
input["access"] = "item"
assert input["access"] in {"item", "list", "tree"}, "Input Access needs to be either 'item', 'list' or 'tree'"
for output in component["outputs"]:
assert "type" in output, "Input needs a type"
assert "name" in output, "Input needs a name"
assert "description" in output, "Input needs a description"
if not "nick-name" in output:
output["nick-name"] = output["name"]
if not "access" in output:
output["access"] = "item"
if "icon" in component:
# convert icon (a path) to a base64 string
icon_path = os.path.join(badger_dir, component["icon"])
assert os.path.exists(icon_path), "Could not find icon file: {}".format(icon_path)
# bytes = System.IO.File.ReadAllBytes(icon_path)
# icon_base64 = System.Convert.ToBase64String(bytes)
# component["icon"] = icon_path
return badger_config


COMPONENT_TEMPLATE = u"""
using System;
using System.Collections.Generic;
using Grasshopper.Kernel.Types;
using Grasshopper.Kernel;
using Hive.IO.EnergySystems;
namespace Hive.IO.Gh${subcategory}
{
public class ${abbreviation} : GH_Component
{
public ${abbreviation}()
: base("${name}", "${abbreviation}",
"${description}",
"${category}", "${subcategory}")
{
}
public override GH_Exposure Exposure => GH_Exposure.${exposure};
protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
{
% for i in register_inputs:
${i}
% endfor
}
protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
{
% for o in register_outputs:
${o}
% endfor
}
protected override void SolveInstance(IGH_DataAccess DA)
{
% for i in set_inputs:
${i}
% endfor
${solve_instance}
% for o in set_outputs:
${o}
% endfor
}
protected override System.Drawing.Bitmap Icon => Properties.Resources.${icon};
public override Guid ComponentGuid => new Guid("${id}");
}
}
"""

SOLVE_INSTANCE = "// TODO"

if __name__ == '__main__':
filename = "epw_reader\\Hive.Core.epw_reader.json"
config_path = os.path.join(os.path.dirname(__file__), filename)
main(config_path)
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def compile_surface_tech_to_json():
JSON_OUT = "surface_tech_module_types.json"
JSON_PATH = os.path.join(OUT_DIR, JSON_OUT)

CSV_FILES = ["pv_efficiency.csv", "st_efficiency.csv"] # not yet supported: "pvt_efficiency.csv"
CATEGORIES = ["Photovoltaic (PV)", "Solar Thermal (ST)"] # not yet supported:"Photovoltaic and Thermal (PVT)"
CSV_FILES = ["pv_efficiency.csv", "st_efficiency.csv", "bipv_efficiency.csv"] # not yet supported: "pvt_efficiency.csv"
CATEGORIES = ["Photovoltaic (PV)", "Solar Thermal (ST)", "Building Integrated Photovoltaic (BIPV)"] # not yet supported:"Photovoltaic and Thermal (PVT)"

HEADERS = {
"Type": str,
Expand Down
Loading

0 comments on commit ce83574

Please sign in to comment.