Custom Honeybee Opaque Material Not Connecting to HB Opaque Construction

Hello dear Honeybee Community and Developers,
@chris @mostapha
I’m trying to create a custom component that mimics the functionality of HB Opaque Material, with the goal of using it as input to the HB Opaque Construction component.

I’ve written a Grasshopper Python component to define a material, and while the script runs without errors, I’m encountering a problem when I try to connect its output to the HB Opaque Construction component. The error I get is:

1. Solution exception:Expected opaque energy material for construction. Got <type 'PyObject'>.

You can see the error in the attached image.

Here is the relevant code I’m using:

# Grasshopper Python Component for PCM Material Definition

# Import Honeybee modules
try:
    from honeybee.typing import clean_ep_string
except ImportError as e:
    raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))

try:
    from honeybee_energy.material.opaque import EnergyMaterial
except ImportError as e:
    raise ImportError('\nFailed to import honeybee_energy:\n\t{}'.format(e))

# Validate required inputs and build detailed messages
missing = []
error_messages = []

if name is None:
    missing.append("name")
    error_messages.append("Input 'name' (material name) is missing.")
if thickness is None:
    missing.append("thickness")
    error_messages.append("Input 'thickness' is missing.")
if conductivity is None:
    missing.append("conductivity")
    error_messages.append("Input 'conductivity' is missing.")
if density is None:
    missing.append("density")
    error_messages.append("Input 'density' is missing.")
if specific_heat is None:
    missing.append("specific_heat")
    error_messages.append("Input 'specific_heat' is missing.")
if temp_coeff is None:
    missing.append("temp_coeff")
    error_messages.append("Input 'temp_coeff' (temperature coefficient) is missing.")
if not temperature_list:
    missing.append("temperature_list")
    error_messages.append("Input 'temperature_list' is empty or missing.")
if not enthalpy_list:
    missing.append("enthalpy_list")
    error_messages.append("Input 'enthalpy_list' is empty or missing.")

if missing:
    raise ValueError("\n" + "\n".join(error_messages))

# Set default values for optional inputs
roughness = "MediumRough" if roughness is None else roughness
thermal_absorptance = 0.9 if thermal_absorptance is None else thermal_absorptance
solar_absorptance = 0.7 if solar_absorptance is None else solar_absorptance
visible_absorptance = solar_absorptance if visible_absorptance is None else visible_absorptance

# Clean the material name
clean_name = clean_ep_string(name)

# Create the Honeybee EnergyMaterial
material_def_out = EnergyMaterial(
    clean_name,
    thickness,
    conductivity,
    density,
    specific_heat,
    roughness,
    thermal_absorptance,
    solar_absorptance,
    visible_absorptance
)

# The phase change definition can be handled separately if needed
# ... (rest of your phase change code if required)

Hey @hamed.sangin ,

Your code looks correct there and I think I know what is going on. Are you in Rhino 8 and are you using the Python 3 Grasshopper component? If so, that is not compatible with all of the LBT-Grasshopper components because they use GHPython (a flavor of IronPython 2) instead of cPython 3.

To make a component that works with the LBT-Grasshopper components, double-click a blank part of the Grasshopper canvas and type #GHPython to bring up a GHPython component that can work with any LBT-Grasshopper component. Then just edit the GHPython component inputs/outputs and copy/paste your code in there. Then, it all should work.

dear @Chris
Thanks for your help — that was exactly the issue!
My component is now working.

Do you think it will be compatible with Rhino 8’s Python 3 Grasshopper components in the future?

2 Likes

It’s possible to do this but it is more likely for us to switch from using the older GHPython component to the new Rhino 8 IronPython 2 component instead of Rhino 8’s cPython 3 component. Most Rhinocommon functions just perform a lot better in IronPython than cPython so many components would be taking a significant performance hit if we converted all of the LBT components to use cPython 3.

Maybe we might do a strategy of using IronPython for some components and cPython for others depending on how heavily a given component uses Rhinocommon. In any event, we will consider making this change closer to the Rhino 9 release when we no longer have to worry about supporting people who are still using Rhino 7.