class CreateOctree(Function): """Generate an octree from a Radiance folder.""" # inputs include_aperture = Inputs.str( default='include', description= 'A value to indicate if the static aperture should be included in ' 'octree. Valid values are include and exclude. Default is include.', spec={ 'type': 'string', 'enum': ['include', 'exclude'] }) black_out = Inputs.str( default='default', description= 'A value to indicate if the black material should be used. Valid ' 'values are default and black. Default value is default.', spec={ 'type': 'string', 'enum': ['black', 'default'] }) model = Inputs.folder(description='Path to Radiance model folder.', path='model') @command def create_octree(self): return 'honeybee-radiance octree from-folder model --output scene.oct ' \ '--{{self.include_aperture}}-aperture --{{self.black_out}}' # outputs scene_file = Outputs.file(description='Output octree file.', path='scene.oct')
class MergeImages(Function): """Merge several .HDR image files with similar starting name into one.""" folder = Inputs.folder( description='Target folder with the input .HDR image files.', path='input_folder') name = Inputs.str(description='Base name for files to be merged.', default='view') extension = Inputs.str( description='File extension including the . before the extension ' '(e.g. .HDR, .pic, .unf)', default='.unf') scale_factor = Inputs.float( description='A number that will be used to scale the dimensions of the ' 'output image as it is filtered for anti-aliasing.', default=1) @command def merge_files(self): return 'honeybee-radiance view merge input_folder view ' \ '{{self.extension}} --scale-factor {{self.scale_factor}} ' \ '--name {{self.name}}' result_image = Outputs.file(description='Output combined image file.', path='{{self.name}}.HDR')
class RayTracingPicture(Function): """Run ray-tracing with rpict command for an input octree and a view file..""" view = Inputs.file(description='Input view file.', path='view.vf') scene_file = Inputs.file( description='Path to an octree file to describe the scene.', path='scene.oct') radiance_parameters = Inputs.str( description='Radiance parameters to be exposed within recipes. -h is ' 'usually already included in the fixed_radiance_parameters and -I will ' 'be overwritten based on the input metric.', default='-ab 2') metric = Inputs.str( description= 'Text for the type of metric to be output from the calculation. ' 'Choose from: illuminance, irradiance, luminance, radiance.', default='luminance', spec={ 'type': 'string', 'enum': ['illuminance', 'irradiance', 'luminance', 'radiance'] }) resolution = Inputs.int( description= 'An integer for the maximum dimension of the image in pixels ' '(either width or height depending on the input view angle and type).', spec={ 'type': 'integer', 'minimum': 1 }, default=512) scale_factor = Inputs.float( description= 'A number that will be multiplied by the input resolution to ' 'scale the dimensions of the output image. This is useful in workflows if ' 'one plans to re-scale the image after the ray tracing calculation to ' 'improve anti-aliasing.', default=1) ambient_cache = Inputs.file( description='Path to the ambient cache if an overture calculation was ' 'specified. If unspecified, no ambient cache will be used.', path='view.amb', optional=True) @command def ray_tracing(self): return 'honeybee-radiance rpict rpict scene.oct view.vf ' \ '--rad-params "{{self.radiance_parameters}}" --metric {{self.metric}} ' \ '--resolution {{self.resolution}} --scale-factor {{self.scale_factor}} ' \ '--output view.HDR' result_image = Outputs.file( description='Path to the High Dynamic Range (HDR) image file of the ' 'input view.', path='view.HDR')
class MergeFiles(Function): """Merge several files with similar starting name into one.""" name = Inputs.str( description='Base name for files to be merged.', default='grid' ) extension = Inputs.str( description='File extension including the . before the extension (e.g. .res, ' '.ill)' ) folder = Inputs.folder( description='Target folder with the input files.', path='input_folder' ) @command def merge_files(self): return 'honeybee-radiance grid merge input_folder grid ' \ ' {{self.extension}} --name {{self.name}}' result_file = Outputs.file( description='Output result file.', path='{{self.name}}{{self.extension}}' )
class CreateRadianceFolder(Function): """Create a Radiance folder from a HBJSON input file. This function creates the folder but doesn't expose information for sensor grids and views. """ input_model = Inputs.file(description='Path to input HBJSON file.', path='model.hbjson') grid_filter = Inputs.str( description= 'Text for a grid identifer or a pattern to filter the sensor grids ' 'of the model that are simulated. For instance, first_floor_* will simulate ' 'only the sensor grids that have an identifier that starts with ' 'first_floor_. By default, all grids in the model will be simulated.', default='*') view_filter = Inputs.str( description='Text for a view identifer or a pattern to filter the views ' 'of the model that are simulated. For instance, first_floor_* will simulate ' 'only the views that have an identifier that starts with first_floor_. By ' 'default, all views in the model will be simulated.', default='*') @command def hbjson_to_rad_folder(self): return 'honeybee-radiance translate model-to-rad-folder model.hbjson ' \ '--grid "{{self.grid_filter}}" --view "{{self.view_filter}}"' model_folder = Outputs.folder(description='Radiance folder.', path='model')
class MapResultInfo(Function): """Get a JSON that specifies the data type and units for comfort map outputs.""" comfort_model = Inputs.str( description='Text for the comfort model of the thermal mapping ' 'simulation. Choose from: pmv, adaptive, utci.', spec={ 'type': 'string', 'enum': ['pmv', 'adaptive', 'utci'] }) run_period = Inputs.str( description= 'The AnalysisPeriod string that dictates the start and end of ' 'the analysis (eg. "6/21 to 9/21 between 8 and 16 @1"). If unspecified, it ' 'will be assumed results are for a full year.', default='') qualifier = Inputs.str( description= 'Text for any options used on the comfort map simulation that ' 'change the output data type of results. For example, the write-set-map text ' 'of the pmv map can be passed here to ensure the output of this command is ' 'for SET instead of operative temperature.', default='') @command def map_results_information(self): return 'ladybug-comfort map map-result-info {{self.comfort_model}} ' \ '--run-period "{{self.run_period}}" --qualifier "{{self.qualifier}}" ' \ '--folder output --log-file results_info.json' results_info_file = Outputs.file( description= 'A JSON that specifies the data type and units for all comfort map ' 'outputs.', path='results_info.json') viz_config_file = Outputs.file( description= 'A JSON that specifies configurations for VTK visualizations.', path='output/config.json') temperature_info = Outputs.file( description= 'A JSON that specifies the data type and units for temperature map ' 'results.', path='output/temperature.json') condition_info = Outputs.file( description='A JSON that specifies the data type and units for thermal ' 'condition map results.', path='output/condition.json') condition_intensity_info = Outputs.file( description='A JSON that specifies the data type and units for ' 'condition intensity map results.', path='output/condition_intensity.json')
class ResultCsvQueryable(Function): """Get a CSV of energy simulation results as an easily query-able SQLite table.""" result_sql = Inputs.file( description='A SQLite file that was generated by EnergyPlus.', path='result.sql', extensions=['sql', 'db', 'sqlite']) model = Inputs.file( description= 'Honeybee model in JSON format that will be matched to results ' 'in the result sql and used to account for triangulated sub-faces, room ' 'multipliers, and any area normalization of results.', path='model.json', extensions=['hbjson', 'json']) output_name = Inputs.str( description= 'An EnergyPlus output name to be retrieved from the result-sql. ' '(eg. Zone Operative Temperature). This can also be a JSON array of names ' 'formatted with [] brackets.') run_period = Inputs.str( description='The name of the run period from which the CSV data will be ' 'selected. (eg. BOSTON LOGAN INTL ARPT ANN CLG .4% CONDNS DB=>MWB).') units = Inputs.str( description='A switch to indicate whether the data in the resulting CSV ' 'should be in SI or IP units. Valid values are "si" and "ip".', default='si', spec={ 'type': 'string', 'enum': ['si', 'ip'] }) normalization = Inputs.str( description= 'A switch to indicate whether the data in the resulting CSV should ' 'be normalized by floor area (in the case of Zone/System data) or surface ' 'area (in the case of Surface data). This has no effect if the requested ' 'data is not normalizable. Valid values are "normalize" and "no-normalize".', default='normalize', spec={ 'type': 'string', 'enum': ['normalize', 'no-normalize'] }) @command def result_csv_queryable(self): return 'honeybee-energy result output-csv-queryable result.sql model.json ' \ '"{{inputs.run-period}}" "{{inputs.output_name}}" --{{inputs.units}} ' \ '--{{inputs.normalization}} --folder output --log-file output/col_names.json' column_names = Outputs.file( description='A list of DataCollection JSONs that match the requested ' 'output name.', path='output.json')
class ConvertToBinary(Function): """Convert a Radiance matrix to a new matrix with 0-1 values.""" # inputs input_mtx = Inputs.file( description='Input Radiance matrix in ASCII format', path='input.mtx') minimum = Inputs.float( description='Minimum range for the values that will be converted to 1.', default=-1 * 10**100) maximum = Inputs.float( description='Maximum range for the values that will be converted to 1.', default=10**100) include_min = Inputs.str( description= 'A flag to include the minimum threshold itself. By default the ' 'threshold value will be included.', default='include', spec={ 'type': 'string', 'enum': ['include', 'exclude'] }) include_max = Inputs.str( description= 'A flag to include the maximum threshold itself. By default the ' 'threshold value will be included.', default='include', spec={ 'type': 'string', 'enum': ['include', 'exclude'] }) reverse = Inputs.str( description= 'A flag to reverse the selection logic. This is useful for cases ' 'that you want to all the values outside a certain range to be converted to 1. ' 'By default the input logic will be used as is.', default='comply', spec={ 'type': 'string', 'enum': ['comply', 'reverse'] }) @command def convert_to_zero_one(self): return 'honeybee-radiance post-process convert-to-binary input.mtx ' \ '--output binary.mtx --maximum {{self.maximum}} ' \ '--minimum {{self.minimum}} --{{self.reverse}} ' \ '--{{self.include_min}}-min --{{self.include_max}}-max' # outputs output_mtx = Outputs.file(description='Newly created binary matrix.', path='binary.mtx')
class Count(Function): """Count values in a row that meet a certain criteria.""" # inputs input_mtx = Inputs.file( description='Input Radiance matrix in ASCII format', path='input.mtx') minimum = Inputs.float( description='Minimum range for the values that should be counted.', default=-1 * 10**100) maximum = Inputs.float( description='Maximum range for the values that should be counted.', default=10**100) include_min = Inputs.str( description= 'A flag to include the minimum threshold itself. By default the ' 'threshold value will be included.', default='include', spec={ 'type': 'string', 'enum': ['include', 'exclude'] }) include_max = Inputs.str( description= 'A flag to include the maximum threshold itself. By default the ' 'threshold value will be included.', default='include', spec={ 'type': 'string', 'enum': ['include', 'exclude'] }) reverse = Inputs.str( description= 'A flag to reverse the selection logic. This is useful for cases ' 'that you want to all the values outside a certain range. By default the input ' 'logic will be used as is.', default='comply', spec={ 'type': 'string', 'enum': ['comply', 'reverse'] }) @command def count_values(self): return 'honeybee-radiance post-process count input.mtx ' \ '--output counter.mtx --maximum {{self.maximum}} ' \ '--minimum {{self.minimum}} --{{self.reverse}} ' \ '--{{self.include_min}}-min --{{self.include_max}}-max' # outputs output_mtx = Outputs.file(description='Newly created binary matrix.', path='counter.mtx')
class DaylightContribution(Function): """ Calculate daylight contribution for a grid of sensors from a series of modifiers using rcontrib command. """ radiance_parameters = Inputs.str( description='Radiance parameters. -I and -aa 0 are already included in ' 'the command.', default='') fixed_radiance_parameters = Inputs.str( description='Radiance parameters. -I and -aa 0 are already included in ' 'the command.', default='-aa 0') calculate_values = Inputs.str( description='A switch to indicate if the values should be multiplied. ' 'Otherwise the contribution is calculated as a coefficient. Default is set to ' 'value. Use coeff for contribution', default='value', spec={ 'type': 'string', 'enum': ['value', 'coeff'] }) sensor_count = Inputs.int( description='Number of maximum sensors in each generated grid.', spec={ 'type': 'integer', 'minimum': 1 }) modifiers = Inputs.file( description= 'Path to modifiers file. In most cases modifiers are sun modifiers.', path='suns.mod') sensor_grid = Inputs.file(description='Path to sensor grid files.', path='grid.pts', extensions=['pts']) scene_file = Inputs.file( description='Path to an octree file to describe the scene.', path='scene.oct', extensions=['oct']) @command def run_daylight_coeff(self): return 'honeybee-radiance dc scontrib scene.oct grid.pts suns.mod ' \ '--{{self.calculate_values}} --sensor-count {{self.sensor_count}} ' \ '--rad-params "{{self.radiance_parameters}}" --rad-params-locked ' \ '"{{self.fixed_radiance_parameters}}" --output results.ill' result_file = Outputs.file(description='Output result file.', path='results.ill')
class BaselineOrientationSimPars(Function): """Get SimulationParameters with different north angles for a baseline building sim. """ ddy = Inputs.file( description='A DDY file with design days to be included in the ' 'SimulationParameter', path='input.ddy', extensions=['ddy']) run_period = Inputs.str( description= 'An AnalysisPeriod string or an IDF RunPeriod string to set the ' 'start and end dates of the simulation (eg. "6/21 to 9/21 between 0 and 23 @1").' ' If None, the simulation will be annual.', default='') north = Inputs.int( description= 'A number from -360 to 360 for the counterclockwise difference ' 'between North and the positive Y-axis in degrees. 90 is west; 270 is east', default=0, spec={ 'type': 'integer', 'maximum': 360, 'minimum': -360 }) filter_des_days = Inputs.str( description= 'A switch for whether the ddy-file should be filtered to only ' 'include 99.6 and 0.4 design days', default='filter-des-days', spec={ 'type': 'string', 'enum': ['filter-des-days', 'all-des-days'] }) @command def baseline_orientation_sim_pars(self): return 'honeybee-energy settings orientation-sim-pars input.ddy ' \ '0 90 180 270 --run-period "{{self.run_period}}" --start-north ' \ '{{self.north}} --{{self.filter_des_days}} --folder output ' \ '--log-file output/sim_par_info.json' sim_par_list = Outputs.dict( description= 'A JSON array that includes information about generated simulation ' 'parameters.', path='output/sim_par_info.json') output_folder = Outputs.folder( description='Output folder with the simulation parameters.', path='output')
class AddRemoveSkyMatrix(Function): """Remove direct sky from total sky and add direct sun.""" total_sky_matrix = Inputs.file( description='Path to matrix for total sky contribution.', path='sky.ill', extensions=['ill', 'dc']) direct_sky_matrix = Inputs.file( description='Path to matrix for direct sky contribution.', path='sky_dir.ill', extensions=['ill', 'dc']) sunlight_matrix = Inputs.file( description='Path to matrix for direct sunlight contribution.', path='sun.ill', extensions=['ill', 'dc']) conversion = Inputs.str( description= 'Conversion as a string which will be passed to rmtxop -c option.', default=' ') output_format = Inputs.str( default='a', description='Output file format. a for ASCII, d for double, f for ' 'float and c for RGBE color.', spec={ 'type': 'string', 'enum': ['a', 'd', 'f', 'c'] }) header = Inputs.str( default='remove', description= 'An input to indicate if header should be kept or removed from the' 'output matrix.', spec={ 'type': 'string', 'enum': ['keep', 'remove'] }) @command def create_matrix(self): return 'honeybee-radiance mtxop operate-three sky.ill sky_dir.ill sun.ill ' \ '--operator-one "-" --operator-two "+" --{{self.header}}-header ' \ '--conversion "{{self.conversion}}" --output-mtx final.ill ' \ '--output-format {{self.output_format}}' results_file = Outputs.file(description='Radiance matrix file.', path='final.ill')
class AirMap(Function): """Get CSV files with maps of air temperatures or humidity from EnergyPlus results. """ result_sql = Inputs.file( description= 'A SQLite file that was generated by EnergyPlus and contains ' 'hourly or sub-hourly thermal comfort results.', path='result.sql', extensions=['sql', 'db', 'sqlite'], optional=True) enclosure_info = Inputs.file( description='A JSON file containing information about the radiant ' 'enclosure that sensor points belong to.', path='enclosure_info.json', extensions=['json']) epw = Inputs.file( description='Weather file used to estimate conditions for any outdoor ' 'sensors.', path='weather.epw', extensions=['epw']) run_period = Inputs.str( description= 'An AnalysisPeriod string to set the start and end dates of the ' 'analysis (eg. "6/21 to 9/21 between 8 and 16 @1"). If unspecified, results ' 'will be annual.', default='') metric = Inputs.str( description= 'A switch to note whether the the output matrix should be with ' 'relative humidity or air temperature values.', default='air-temperature', spec={ 'type': 'string', 'enum': ['air-temperature', 'relative-humidity'] }) @command def run_air_map(self): return 'ladybug-comfort map air result.sql enclosure_info.json weather.epw ' \ '--run-period "{{self.run_period}}" --{{self.metric}} ' \ '--output-file air.csv' air_map = Outputs.file( description= 'CSV file containing a map of air temperatures or humidity.', path='air.csv')
class SimParSizing(Function): """Get a SimulationParameter JSON with outputs for peak loads and HVAC sizing.""" ddy = Inputs.file( description='A DDY file with design days to be included in the ' 'SimulationParameter', path='input.ddy', extensions=['ddy']) load_type = Inputs.str( description= 'Text to indicate the type of load. Choose from (Total, Sensible, ' 'Latent, All)', default='Total', spec={ 'type': 'string', 'enum': ['Total', 'Sensible', 'Latent', 'All'] }) north = Inputs.int( description= 'A number from -360 to 360 for the counterclockwise difference ' 'between North and the positive Y-axis in degrees. 90 is west; 270 is east', default=0, spec={ 'type': 'integer', 'maximum': 360, 'minimum': -360 }) filter_des_days = Inputs.str( description= 'A switch for whether the ddy-file should be filtered to only ' 'include 99.6 and 0.4 design days', default='filter-des-days', spec={ 'type': 'string', 'enum': ['filter-des-days', 'all-des-days'] }) @command def create_sim_param(self): return 'honeybee-energy settings sizing-sim-par input.ddy ' \ '--load-type {{self.load_type}} --north {{self.north}} ' \ '--{{self.filter_des_days}} --output-file sim_par.json' sim_par_json = Outputs.file( description='SimulationParameter JSON with outputs for peak loads and ' 'HVAC sizing.', path='sim_par.json')
class RayTracingPointInTime(Function): """Run ray-tracing and post-process the results for a point-in-time simulation.""" radiance_parameters = Inputs.str( description='Radiance parameters to be exposed within recipes. -h is ' 'usually already included in the fixed_radiance_parameters and -I will ' 'be overwritten based on the input metric.', default='-ab 2') metric = Inputs.str( description= 'Text for the type of metric to be output from the calculation. ' 'Choose from: illuminance, irradiance, luminance, radiance.', default='illuminance', spec={ 'type': 'string', 'enum': ['illuminance', 'irradiance', 'luminance', 'radiance'] }) fixed_radiance_parameters = Inputs.str( description= 'Parameters that are meant to be fixed for a given recipe and ' 'should not be overwritten by radiance_parameters input.', default='-h') grid = Inputs.file(description='Input sensor grid.', path='grid.pts') scene_file = Inputs.file( description='Path to an octree file to describe the scene.', path='scene.oct') bsdf_folder = Inputs.folder( description='Folder containing any BSDF files needed for ray tracing.', path='model/bsdf', optional=True) @command def ray_tracing(self): return 'honeybee-radiance raytrace point-in-time scene.oct grid.pts ' \ '--rad-params "{{self.radiance_parameters}}" --rad-params-locked ' \ '"{{self.fixed_radiance_parameters}}" --metric {{self.metric}} ' \ '--output grid.res' result = Outputs.file( description= 'Point-in-time result file. The result for each sensor is in a ' 'new line of the file. Values are in standard SI units of the input ' 'metric (lux, W/m2, cd/m2, W/m2-sr).', path='grid.res')
class CreateSkyMatrix(Function): """Generate a sun-up sky matrix.""" north = Inputs.int( description='An angle for north direction. Default is 0.', default=0, spec={ 'type': 'integer', 'maximum': 360, 'minimum': 0 }) sky_component = Inputs.str( description='A switch for generating sun-only using -d or exclude sun ' 'contribution using -s. The default is an empty string for including both.', default=' ', spec={ 'type': 'string', 'enum': ['-s', '-d', ' '] }) wea = Inputs.file(description='Path to a wea file.', extensions=['wea'], path='sky.wea') @command def generate_sky_matrix(self): return 'gendaymtx -u -O0 -r {{self.north}} -v {{self.sky_component}} sky.wea > sky.mtx' sky_matrix = Outputs.file(description='Output Sky matrix', path='sky.mtx')
class EnergyUseIntensity(Function): """Get information about energy use intensity from energy simulation SQLite files.""" result_folder = Inputs.folder( description='Path to folder containing SQLite files that were generated ' 'by EnergyPlus. This can be a single EnergyPlus simulation folder or ' 'it can be a folder with multiple sql files, in which case EUI will ' 'be computed across all results.', path='result_folder') units = Inputs.str( description= 'A switch to indicate whether the data in the resulting JSON ' 'should be in SI or IP units. Valid values are "si" and "ip".', default='si', spec={ 'type': 'string', 'enum': ['si', 'ip'] }) @command def energy_use_intensity(self): return 'honeybee-energy result energy-use-intensity result_folder ' \ '--{{inputs.units}} --output-file output.json' eui_json = Outputs.file( description= 'A JSON object with the following keys - eui, total_floor_area, ' 'total_energy, end_uses. The eui value is the energy use intensity across ' 'the total floor area. The end_uses value is a dictionary containing a ' 'breakdown of the eui by end use.', path='output.json')
class EpwToWea(Function): """Translate an .epw file to a .wea file.""" epw = Inputs.file(description='Weather file.', path='weather.epw', extensions=['epw']) period = Inputs.str( description= 'An AnalysisPeriod string to filter the datetimes in the resulting ' 'Wea (eg. "6/21 to 9/21 between 8 and 16 @1"). Note that the timestep ' 'of the analysis period should match the input timestep and a * must be at ' 'the end of the string if the input epw is for a leap year. If None, ' 'the Wea will be annual.', default='') timestep = Inputs.int( description= 'An integer to set the number of time steps per hour. Default is 1 ' 'for one value per hour. Note that this input will only do a linear ' 'interpolation over the data in the epw file.', default=1) @command def epw_to_wea(self): return 'ladybug translate epw-to-wea weather.epw ' \ '--analysis-period "{{self.period}}" --timestep {{self.timestep}} ' \ '--output-file weather.wea' wea = Outputs.file(description='A wea file generated from the input epw.', path='weather.wea')
class AddRemoveSkyMatrixWithConversion(AddRemoveSkyMatrix): """Remove direct sky from total sky and add direct sun.""" conversion = Inputs.str( description='conversion as a string which will be passed to -c', default='47.4 119.9 11.6') output_format = Inputs.str(default='-fa', spec={ 'type': 'string', 'enum': ['-fa', '-fd'] }) @command def create_matrix(self): return 'rmtxop {{self.output_format}} sky.ill + -s -1.0 sky_dir.ill + sun.ill ' \ '-c {{self.conversion}} | getinfo - > final.ill'
class ModelOccSchedules(Function): """Translate a Model's occupancy schedules into a JSON of 0/1 values. This JSON is useful in workflows that compute thermal comfort percent, daylight autonomy, etc. """ model = Inputs.file( description='Honeybee model in JSON format.', path='model.json', extensions=['hbjson', 'json'] ) period = Inputs.str( description='An AnalysisPeriod string to dictate the start and end of the ' 'exported occupancy values (eg. "6/21 to 9/21 between 0 and 23 @1"). Note ' 'that the timestep of the period will determine the timestep of output ' 'values. If unspecified, the values will be annual.', default='' ) threshold = Inputs.float( description='A number between 0 and 1 for the threshold at and above which ' 'a schedule value is considered occupied.', default=0.1, spec={'type': 'number', 'maximum': 1, 'minimum': 0} ) @command def export_model_occ_schedules(self): return 'honeybee-energy translate model-occ-schedules model.json ' \ '--threshold {{self.threshold}} --period "{{self.period}}" ' \ '--output-file occ_schedules.json' occ_schedule_json = Outputs.file( description='An occupancy schedule JSON that is useful in workflows like ' 'thermal comfort percent, daylight autonomy, etc.', path='occ_schedules.json' )
class AdjustSkyForMetric(Function): """Adjust a sky file to ensure it is suitable for a given metric. Specifcally, this ensures that skies being created with gendaylit have a -O option that aligns with visible vs. solar energy. """ sky = Inputs.file( description='Path to a .sky file to be adjusted based on the metric.', path='input.sky') metric = Inputs.str( description= 'Text for the type of metric to be output from the calculation. ' 'Choose from: illuminance, irradiance, luminance, radiance.', default='illuminance', spec={ 'type': 'string', 'enum': ['illuminance', 'irradiance', 'luminance', 'radiance'] }) @command def adjust_sky_for_metric(self): return 'honeybee-radiance sky adjust-for-metric {{self.sky}} ' \ '--metric {{self.metric}}' adjusted_sky = Outputs.file(description='Adjusted sky file.', path='{{self.metric}}.sky')
class WindowsByRatio(Function): """Add windows to all outdoor walls of a model given a ratio.""" model = Inputs.file(description='Dragonfly model in JSON format.', path='model.dfjson', extensions=['dfjson', 'json']) ratio = Inputs.str( description= 'A number between 0 and 1 (but not perfectly equal to 1) for the ' 'desired ratio between window area and wall area. If multiple values are ' 'input here (each separated by a space), different WindowParameters will be ' 'assigned based on cardinal direction, starting with north and moving ' 'clockwise.', default='0.4') @command def windows_by_ratio(self): return 'dragonfly edit windows-by-ratio model.dfjson {{self.ratio}} ' \ '--output-file new_model.dfjson' new_model = Outputs.file( description='Dragonfly Model JSON with window parameters set based on ' 'the input ratio.', path='new_model.dfjson')
class CreateRadianceFolderView(Function): """Create a Radiance folder from a HBJSON input file.""" input_model = Inputs.file(description='Path to input HBJSON file.', path='model.hbjson') view_filter = Inputs.str( description='Text for a view identifer or a pattern to filter the views ' 'of the model that are simulated. For instance, first_floor_* will simulate ' 'only the views that have an identifier that starts with first_floor_. By ' 'default, all views in the model will be simulated.', default='*') @command def hbjson_to_rad_folder(self): return 'honeybee-radiance translate model-to-rad-folder model.hbjson ' \ '--view "{{self.view_filter}}" --view-check' model_folder = Outputs.folder(description='Radiance folder.', path='model') views = Outputs.list(description='Views information.', path='model/view/_info.json') views_file = Outputs.file(description='Views information JSON file.', path='model/view/_info.json')
class SimParDefault(Function): """Get a SimulationParameter JSON with default outputs for energy use only.""" ddy = Inputs.file( description='A DDY file with design days to be included in the ' 'SimulationParameter', path='input.ddy', extensions=['ddy']) run_period = Inputs.str( description= 'An AnalysisPeriod string or an IDF RunPeriod string to set the ' 'start and end dates of the simulation (eg. "6/21 to 9/21 between 0 and 23 @1").' ' If None, the simulation will be annual.', default='') north = Inputs.int( description= 'A number from -360 to 360 for the counterclockwise difference ' 'between North and the positive Y-axis in degrees. 90 is west; 270 is east', default=0, spec={ 'type': 'integer', 'maximum': 360, 'minimum': -360 }) filter_des_days = Inputs.str( description= 'A switch for whether the ddy-file should be filtered to only ' 'include 99.6 and 0.4 design days', default='filter-des-days', spec={ 'type': 'string', 'enum': ['filter-des-days', 'all-des-days'] }) @command def create_sim_param(self): return 'honeybee-energy settings default-sim-par input.ddy ' \ '--run-period "{{self.run_period}}" --north {{self.north}} ' \ '--{{self.filter_des_days}} --output-file sim_par.json' sim_par_json = Outputs.file( description= 'SimulationParameter JSON with default outputs for energy use', path='sim_par.json')
class DaylightCoefficient(Function): """Calculate daylight coefficient for a grid of sensors from a sky matrix.""" radiance_parameters = Inputs.str( description= 'Radiance parameters. -I, -c 1 and -aa 0 are already included in ' 'the command.', default='') fixed_radiance_parameters = Inputs.str( description= 'Radiance parameters. -I, -c 1 and -aa 0 are already included in ' 'the command.', default='-aa 0') sensor_count = Inputs.int( description='Number of maximum sensors in each generated grid.', spec={ 'type': 'integer', 'minimum': 1 }) sky_matrix = Inputs.file(description='Path to a sky matrix.', path='sky.mtx', extensions=['mtx', 'smx']) sky_dome = Inputs.file(description='Path to a sky dome.', path='sky.dome') sensor_grid = Inputs.file(description='Path to sensor grid files.', path='grid.pts', extensions=['pts']) scene_file = Inputs.file( description='Path to an octree file to describe the scene.', path='scene.oct', extensions=['oct']) @command def run_daylight_coeff(self): return 'honeybee-radiance dc scoeff scene.oct grid.pts sky.dome sky.mtx ' \ '--sensor-count {{self.sensor_count}} --output results.ill --rad-params ' \ '"{{self.radiance_parameters}}" --rad-params-locked '\ '"{{self.fixed_radiance_parameters}}"' result_file = Outputs.file(description='Output result file.', path='results.ill')
class AnnualDaylightMetrics(Function): """Calculate annual daylight metrics for annual daylight simulation.""" folder = Inputs.folder( description='This folder is an output folder of annual daylight recipe. Folder ' 'should include grids_info.json and sun-up-hours.txt. The command uses the list ' 'in grids_info.json to find the result files for each sensor grid.', path='raw_results' ) schedule = Inputs.file( description='Path to an annual schedule file. Values should be 0-1 separated ' 'by new line. If not provided an 8-5 annual schedule will be created.', path='schedule.txt', optional=True ) thresholds = Inputs.str( description='A string to change the threshold for daylight autonomy and useful ' 'daylight illuminance. Valid keys are -t for daylight autonomy threshold, -lt ' 'for the lower threshold for useful daylight illuminance and -ut for the upper ' 'threshold. The defult is -t 300 -lt 100 -ut 3000. The order of the keys is not ' 'important and you can include one or all of them. For instance if you only ' 'want to change the upper threshold to 2000 lux you should use -ut 2000 as ' 'the input.', default='-t 300 -lt 100 -ut 3000' ) @command def calculate_annual_metrics(self): return 'honeybee-radiance post-process annual-daylight raw_results ' \ '--schedule schedule.txt {{self.thresholds}} --sub_folder ../metrics' # outputs annual_metrics = Outputs.folder( description='Annual metrics folder. This folder includes all the other ' 'subfolders which are also exposed as separate outputs.', path='metrics' ) daylight_autonomy = Outputs.folder( description='Daylight autonomy results.', path='metrics/da' ) continuous_daylight_autonomy = Outputs.folder( description='Continuous daylight autonomy results.', path='metrics/cda' ) useful_daylight_illuminance_lower = Outputs.folder( description='Lower useful daylight illuminance results.', path='metrics/udi_lower' ) useful_daylight_illuminance = Outputs.folder( description='Useful daylight illuminance results.', path='metrics/udi' ) useful_daylight_illuminance_upper = Outputs.folder( description='Upper useful daylight illuminance results.', path='metrics/udi_upper' )
class MatrixMultiplication(Function): """Multiply a matrix with conversation numbers.""" conversion = Inputs.str( description='conversion as a string which will be passed to -c', default='47.4 119.9 11.6' ) input_matrix = Inputs.file( description='Path to input matrix.', path='input.ill' ) output_format = Inputs.str(default='-fa') @command def create_matrix(self): return 'rmtxop {{self.output_format}} input.ill -c {{self.conversion}} | ' \ 'getinfo - > output.ill' output_matrix = Outputs.file(description='New matrix file.', path='output.ill')
class RayTracingDaylightFactor(Function): """Run ray-tracing and post-process the results for a daylight factor simulation.""" radiance_parameters = Inputs.str( description= 'Radiance parameters to be exposed within recipes. -I and -h are ' 'usually already included in the fixed_radiance_parameters.', default='-ab 2') sky_illum = Inputs.int( description='Sky illuminance level for the sky included in octree.', default=100000) fixed_radiance_parameters = Inputs.str( description= 'Parameters that are meant to be fixed for a given recipe and ' 'should not be overwritten by radiance_parameters input.', default='-I -h') grid = Inputs.file(description='Input sensor grid.', path='grid.pts') scene_file = Inputs.file( description='Path to an octree file to describe the scene.', path='scene.oct') bsdf_folder = Inputs.folder( description='Folder containing any BSDF files needed for ray tracing.', path='model/bsdf', optional=True) @command def ray_tracing(self): return 'honeybee-radiance raytrace daylight-factor scene.oct grid.pts ' \ '--rad-params "{{self.radiance_parameters}}" --rad-params-locked ' \ '"{{self.fixed_radiance_parameters}}" --sky-illum {{self.sky_illum}} ' \ '--output grid.res' result = Outputs.file( description= 'Daylight factor results file. The results for each sensor is in a ' 'new line.', path='grid.res')
class PrevailingTemperature(Function): """Get Adaptive comfort Prevailing Outdoor Temperature from an EPW weather file.""" epw = Inputs.file( description='Weather file used to obtain prevailing temperatures.', path='weather.epw', extensions=['epw'] ) comfort_par = Inputs.str( description='An AdaptiveParameter string to customize the assumptions of ' 'the Adaptive comfort model.', default='--standard ASHRAE-55' ) run_period = Inputs.str( description='An AnalysisPeriod string to set the start and end dates of the ' 'analysis (eg. "6/21 to 9/21 between 8 and 16 @1"). If unspecified, results ' 'will be annual.', default='' ) output_format = Inputs.str( description='A switch to note whether the output data should be in CSV or ' 'JSON format.', default='csv', spec={'type': 'string', 'enum': ['csv', 'json']} ) order_by = Inputs.str( description='A switch to note whether whether the CSV should be written ' 'with rows or columns.', default='columns', spec={'type': 'string', 'enum': ['columns', 'rows']} ) @command def get_prevailing_temperature(self): return 'ladybug-comfort epw prevailing weather.epw ' \ '--comfort-par "{{self.comfort_par}}" --run-period "{{self.run_period}}" ' \ '--{{self.output_format}} --{{self.order_by}} --output-file prevailing.csv' prevailing_temperature = Outputs.file( description='CSV or JSON file containing list of prevailing temperatures ' 'in celsius.', path='prevailing.csv' )
class AirSpeedJson(Function): """Get a JSON of air speeds that can be used as input for the mtx functions.""" epw = Inputs.file( description='Weather file used to obtain prevailing temperatures.', path='weather.epw', extensions=['epw'] ) enclosure_info = Inputs.file( description='A JSON file containing information about the radiant ' 'enclosure that sensor points belong to.', path='enclosure_info.json', extensions=['json'] ) multiply_by = Inputs.float( description='A number to denote a factor that EPW wind speeds should be ' 'multipled by in order to represent air speeds at ground level.', default=0.5 ) indoor_air_speed = Inputs.file( description='The path to a CSV file containing a single number for air speed ' 'in m/s or multiple numbers (with one value per row) that align with the ' 'length of the run-period. This will be used for all ' 'indoor comfort evaluation.', path='in_speed.txt', optional=True ) outdoor_air_speed = Inputs.file( description='The path to a CSV file containing a single number for air speed ' 'in m/s or multiple numbers (with one value per row) that align with the ' 'length of the run-period. If None, the resulting air speed JSON will use ' 'the EPW wind speed times the multiply-by value.', path='out_speed.txt', optional=True ) run_period = Inputs.str( description='An AnalysisPeriod string to set the start and end dates of the ' 'analysis (eg. "6/21 to 9/21 between 8 and 16 @1"). If unspecified, results ' 'will be annual.', default='' ) @command def get_air_speed_json(self): return 'ladybug-comfort epw air-speed-json weather.epw enclosure_info.json ' \ '--multiply-by {{self.multiply_by}} --indoor-air-speed in_speed.txt ' \ '--outdoor-air-speed out_speed.txt --run-period "{{self.run_period}}" ' \ '--output-file air_speed.json' air_speeds = Outputs.file( description='A JSON of air speeds that can be used as input for the mtx ' 'functions.', path='air_speed.json' )