Files
old-krovovi-kalkulator/helix/doc_gen_params_builder.py
2017-11-07 09:23:57 +01:00

167 lines
7.2 KiB
Python

from base64 import b64encode
import os
from helix.constants.system_type import SystemType
from helix.constants.version import version
class DocGenParamsBuilder(object):
def __init__(self, user_values, system_type, calculator, image_presenter):
self.user_values = user_values
self.system_type = system_type
self.calculator = calculator
self.image_presenter = image_presenter
def build(self):
if self.user_values.system_type() == SystemType.singleTilt:
template_name = 'Helix_Single_Tilt_Template'
else:
template_name = 'Helix_Dual_Tilt_Template'
body = {
**self.site_characterization(),
**self.calculator.documentation_summary_values(),
**self.panel_attributes(),
**self.bom(),
**self.power_stations(),
**self.standalone_inverters(),
**self.subarray_summary(),
}
image_dicts = self.array_image()
list_params = self.convert_dict_params_to_list(body)
images = self.convert_dict_params_to_list(image_dicts, key_name='imageKey', value_name='base64encodedImage')
api_key = os.getenv('SP_DOCGEN_API_KEY', '')
params = {
"apiKey": api_key,
"templateName": template_name,
"nameValuePairs": list_params,
"dynamicImages": images,
}
return params
def site_characterization(self):
panels = self.calculator.get_computed_csv_columns()
return {
'project_name': self.user_values.project_name(),
'building_height': self.user_values.building_height(),
'building_width': self.user_values.building_width(),
'building_length': self.user_values.building_length(),
'parapet_height': self.user_values.building_parapet_height(),
'ballast_block_weight': self.user_values.ballast_block_weight(),
'max_allowable_system_pressure': self.user_values.max_system_pressure(),
'anchor_type': self.user_values.anchor_type().value,
'exposure_category': self.user_values.exposure_category().value,
'exposure_category_transition_distance': self.user_values.exposure_category_transition_distance(),
'wind_speed': self.user_values.wind_speed(),
'spectral_response': self.user_values.spectral_response(),
'seismic_importance_factor': self.user_values.importance_factor(),
'module_type': self.user_values.module_type().value,
'system_type': self.user_values.system_type().display_name(),
'total_modules': len(panels),
'version': version(),
'lb': round(self.calculator.L_B(), 2),
'kz': round(self.calculator.k_z(), 2),
'qz': round(self.calculator.q_z(), 2),
}
def panel_attributes(self):
summary_table = self.calculator.summary_table()
minimum_array_sizes = self.calculator.minimum_array_sizes()
result = {}
for panel_type, values in summary_table.items():
ballast_blocks = values['ballast blocks']
pressure = values['pressure']
anchors = values['anchors']
for wind_zone_index in range(len(ballast_blocks)):
wind_zone = self.system_type.system_constants().wind_zones[wind_zone_index].lower()
prefix = '%d_%s_' % (panel_type.number(), wind_zone)
result[prefix + 'bb'] = ballast_blocks[wind_zone_index]
result[prefix + 'psf'] = pressure[wind_zone_index]
result[prefix + 'anc'] = anchors[wind_zone_index]
for idx, array_size in enumerate(minimum_array_sizes):
wind_zone = self.system_type.system_constants().wind_zones[idx].lower()
result['min_' + wind_zone] = array_size
return result
def bom(self):
bom_values = self.calculator.documentation_bom()
result = {}
for row in bom_values:
result['total_' + row[0]] = row[1]
return result
def power_stations(self):
power_station_string = ""
power_stations = self.user_values.power_stations()
if len(power_stations) > 0:
power_station_string = "\n"
for power_station in self.user_values.power_stations():
power_station_string += "Description: %s\n" % power_station['power_station_description']
power_station_string += "\tQuantity: %s\n" % power_station['power_station_quantity']
power_station_string += "\tAC Run Length: %s\n" % power_station['ac_run_length']
power_station_string += "\tInverters:\n"
for inverter in power_station['inverters']:
power_station_string += "\t\tModel: %s\n" % inverter['model'].label
power_station_string += "\t\tStrings per inverter: %s\n" % inverter['strings_per_inverter']
if inverter.get('sunshade'):
power_station_string += "\t\tSunShade: Yes\n"
if inverter.get('dc_switch'):
power_station_string += "\t\tDC Switch: Yes\n"
power_station_string += "\n"
return {'power_station_string': power_station_string}
def standalone_inverters(self):
inverters_string = ""
for inverter in self.user_values.standalone_inverters():
inverters_string += "\n"
inverters_string += "\tAC Run Length: %s\n" % inverter['ac_run_length']
inverters_string += "\tAttachment Point: %s\n" % inverter['attachment_point'][0]
inverters_string += "\tModel: %s\n" % inverter['model'].label
inverters_string += "\tStrings per inverter: %s\n" % inverter['strings_per_inverter']
if inverter.get('sunshade'):
inverters_string += "\tSunShade: Yes\n"
if inverter.get('dc_switch'):
inverters_string += "\tDC Switch: Yes\n"
return {'standalone_inverter_string': inverters_string}
def subarray_summary(self):
subarray_string = ""
for subarray in self.calculator.subarray_summary():
subarray_string += "\n"
subarray_string += "\tSubarray: %d\n" % subarray.subarray_number
subarray_string += "\tSeismic Anchors: %d\n" % subarray.required_seismic_anchors
subarray_string += "\tWeight: %s lbs\n" % "{:,}".format(round(subarray.weight))
return {'subarrays_string': subarray_string}
def array_image(self):
png_data = self.image_presenter.generate_image(self.calculator.get_computed_csv_columns(),
self.calculator.subarrays)
return {'array_image': b64encode(png_data).decode('utf-8')}
@staticmethod
def convert_list_params_to_dict(list_params):
dict_params = {}
for datum in list_params:
dict_params[datum['name']] = datum['value']
return dict_params
@staticmethod
def convert_dict_params_to_list(dict_params, key_name='name', value_name='value'):
list_params = []
for k, v in dict_params.items():
list_params.append({
key_name: k,
value_name: v
})
return sorted(list_params, key=lambda k: k[key_name])