108 lines
3.5 KiB
Python
108 lines
3.5 KiB
Python
import csv
|
|
from enum import Enum
|
|
from io import StringIO
|
|
|
|
|
|
class PanelDataColumn(Enum):
|
|
Handle = 'HANDLE'
|
|
Blockname = 'BLOCKNAME'
|
|
Subarray = 'SUBARRAY'
|
|
PanelType = 'POS'
|
|
WindZone = 'WIND'
|
|
Ballast = 'BAL'
|
|
LinkTray = 'LT_CALCULATED'
|
|
CrossTray = 'XTRAY'
|
|
WindAnchor = 'ANC'
|
|
SeismicAnchor = 'SEISMIC'
|
|
Coordinate = 'COORDINATE'
|
|
Pressure = 'PSF'
|
|
Id = 'ID'
|
|
PresentedLinkTray = 'LTRAY'
|
|
Xcoord = 'XCOORD'
|
|
Ycoord = 'YCOORD'
|
|
Rotation = 'ANGLE'
|
|
FuzzyWindZone = 'FUZZYWINDZONE'
|
|
|
|
|
|
class CSVDataColumn(Enum):
|
|
PresentedAnchors = "ANC"
|
|
|
|
|
|
class CsvBuilder(object):
|
|
def build_cad_output(self, panels):
|
|
panels.sort(key=lambda x: x.id)
|
|
|
|
|
|
output_columns = [
|
|
PanelDataColumn.Handle, PanelDataColumn.Blockname, PanelDataColumn.WindZone, PanelDataColumn.PanelType,
|
|
PanelDataColumn.Subarray, PanelDataColumn.Pressure, PanelDataColumn.Ballast,
|
|
PanelDataColumn.PresentedLinkTray, PanelDataColumn.CrossTray, CSVDataColumn.PresentedAnchors,
|
|
PanelDataColumn.Id, PanelDataColumn.Xcoord, PanelDataColumn.Ycoord, PanelDataColumn.Rotation
|
|
]
|
|
use_fuzzy_wind_zone = False
|
|
for panel in panels:
|
|
if panel.fuzzy_wind_zone:
|
|
output_columns.append(PanelDataColumn.FuzzyWindZone)
|
|
use_fuzzy_wind_zone = True
|
|
break
|
|
|
|
header_row = [col.value for col in output_columns]
|
|
matrix = [self.format_panel_for_csv(panel, include_fuzzy_wind_zone=use_fuzzy_wind_zone) for panel in panels]
|
|
|
|
return self.output_csv(header_row, matrix)
|
|
|
|
def build_bom_output(self, rows):
|
|
headers = ['Part #', 'Description', 'Total']
|
|
return self.output_csv(headers, rows)
|
|
|
|
def output_csv(self, headers, rows):
|
|
output = StringIO()
|
|
writer = csv.writer(output, dialect='excel-tab', quoting=csv.QUOTE_NONE, quotechar='')
|
|
|
|
writer.writerow(headers)
|
|
writer.writerows(rows)
|
|
return output.getvalue()
|
|
|
|
def format_panel_for_csv(self, panel, include_fuzzy_wind_zone=False):
|
|
row = [
|
|
panel.handle or "",
|
|
panel.blockname or "",
|
|
self.int_to_wind_zone(panel.wind_zone),
|
|
panel.panel_type.number() if panel.panel_type else "",
|
|
panel.subarray,
|
|
round(panel.pressure, 2) if panel.pressure else "",
|
|
self.present_value(panel.ballast),
|
|
self.present_value(panel.presented_link_tray) or '-',
|
|
self.present_value(panel.cross_tray) or '-',
|
|
self.present_anchors(panel.wind_anchors, panel.seismic_anchors),
|
|
panel.id,
|
|
round(panel.original_coordinate.x, 14),
|
|
round(panel.original_coordinate.y, 14),
|
|
round(panel.original_coordinate.rotation, 14)
|
|
]
|
|
if include_fuzzy_wind_zone:
|
|
row.append(int(panel.fuzzy_wind_zone))
|
|
return row
|
|
|
|
def round_two_digits(self, value):
|
|
return round(value, 2)
|
|
|
|
def zero_to_dash(self, value):
|
|
return int(value) or '-'
|
|
|
|
def int_to_wind_zone(self, value):
|
|
if value is None:
|
|
return ""
|
|
return ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"][value]
|
|
|
|
def present_value(self, value, default=''):
|
|
if value is None:
|
|
return default
|
|
return int(value)
|
|
|
|
def present_anchors(self, wind, seismic):
|
|
if not wind and not seismic:
|
|
return '-'
|
|
wind_string = str(int(wind)) if wind != 0 else ''
|
|
return wind_string + 'S' * int(seismic)
|