162 lines
5.2 KiB
Python
162 lines
5.2 KiB
Python
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
|
|
|
|
|
|
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
|
|
|