import csv import json from helix.constants.anchor_type import AnchorType from helix.constants.exposure_category import ExposureCategory from helix.constants.module_type import ModuleType from helix.constants.panel_type import PanelType from helix.constants.system_type import SystemType from helix.models.coordinate import Coordinate from helix.models.panel import PanelData, Panel from helix.models.sql.inverter_brands import InverterBrand class UserValues(object): def __init__(self, store, site): self.store = store self.site = site def project_name(self): return self.site.project_name def project_name_no_spaces(self): return "_".join(self.site.project_name.split()).lower() def building_height(self): return float(self.site.building_height) def building_width(self): return float(self.site.building_width) def building_length(self): return float(self.site.building_length) def building_parapet_height(self): return float(self.site.parapet_height) def module_type(self): return ModuleType(self.site.module_type) def exposure_category(self): return ExposureCategory(self.site.exposure_category) def exposure_category_transition_distance(self): return int(self.site.exposure_transition_distance or 0) def wind_speed(self): return float(self.site.wind_speed or 0) def ballast_block_weight(self): return float(self.site.ballast_block_weight) def module_system_constants(self): return self.system_type().module_constants(self.module_type()) def power_stations(self): return [power_station.to_json() for power_station in self.site.power_stations] def standalone_inverters(self): return [standalone_inverter.to_json() for standalone_inverter in self.site.standalone_inverters] def power_monitors(self): return [power_monitor.to_json() for power_monitor in self.site.power_monitors] def inverter_brands(self): return [inverter_brands.to_json() for inverter_brands in self.site.inverter_brands] def csv(self): csv_data = self.site.cad_file if not csv_data: return None reader = csv.reader(csv_data.splitlines(), dialect='excel-tab') all_headers = next(reader) return [self.parse_csv_row(row, all_headers) for row in reader] def parse_csv_row(self, row, headers): wind_zone_indices = { "A": 0, "B": 1, "C": 2, "D": 3, "E": 4, "F": 5, "G": 6, "H": 7, "I": 8, "J": 9, "K": 10 } wind_zone_index = headers.index(PanelData.WindZone.value) wind_zone = wind_zone_indices[row[wind_zone_index]] panel_type_index = headers.index(PanelData.PanelType.value) panel_type = PanelType.from_number(int(row[panel_type_index])) subarray_index = headers.index(PanelData.Subarray.value) subarray = int(row[subarray_index]) try: xcoord_index = headers.index(PanelData.Xcoord.value) xcoord = float(row[xcoord_index]) except: xcoord = 0 try: ycoord_index = headers.index(PanelData.Ycoord.value) ycoord = float(row[ycoord_index]) except: ycoord = 0 try: rotation_index = headers.index(PanelData.Rotation.value) rotation = float(row[rotation_index]) except: rotation = 0 try: fuzzy_wind_zone_index = headers.index(PanelData.FuzzyWindZone.value) fuzzy_wind_zone = bool(int(row[fuzzy_wind_zone_index])) except: fuzzy_wind_zone = False coordinate = Coordinate(xcoord, ycoord, rotation=rotation) return Panel(handle=row[0], blockname=row[1], wind_zone=wind_zone, panel_type=panel_type, subarray=subarray, coordinate=coordinate, original_coordinate=coordinate, fuzzy_wind_zone=fuzzy_wind_zone) def max_system_pressure(self): return float(self.site.max_psf) def system_type(self): return SystemType(self.site.system_type) def anchor_type(self): return AnchorType(self.site.anchor_type) def spectral_response(self): return float(self.site.spectral_response) def importance_factor(self): return float(self.site.seismic_importance_factor or 1) def user_override_seismic_anchors(self): return self.store.exists('user_override_seismic_anchors') def get_user_provided_seismic_anchors(self): data = json.loads(self.store.get('user_override_seismic_anchors').decode('utf-8')) return [Panel(id=x['panel_id'], seismic_anchors=x['seismic_anchors']) for x in data] def buildings_polygons(self): if self.store.exists('buildings_polygons'): return json.loads(self.store.get('buildings_polygons').decode('utf-8')) else: return [] def is_panel_drawing_inaccurate(self): if self.store.exists('is_drawing_inaccurate'): return json.loads(self.store.get('is_drawing_inaccurate').decode('utf-8')) else: return False # should not happen, but if it does rather not show the warning