first commit
This commit is contained in:
0
test/helpers/__init__.py
Normal file
0
test/helpers/__init__.py
Normal file
35
test/helpers/bom_helper_test.py
Normal file
35
test/helpers/bom_helper_test.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import unittest
|
||||
|
||||
from nose.tools import eq_
|
||||
from numpy import array
|
||||
|
||||
from helix.calculators.bom_helper import get_panel_type_counts
|
||||
from helix.constants.panel_type import PanelType
|
||||
from helix.models.panel import Panel
|
||||
|
||||
|
||||
class BomHelperTest(unittest.TestCase):
|
||||
def test_get_panel_type_counts(self):
|
||||
panels = [Panel(panel_type=PanelType.Corner),
|
||||
Panel(panel_type=PanelType.NorthSouth),
|
||||
Panel(panel_type=PanelType.EastWest),
|
||||
Panel(panel_type=PanelType.Middle),
|
||||
Panel(panel_type=PanelType.Corner),
|
||||
Panel(panel_type=PanelType.EastWest),
|
||||
Panel(panel_type=PanelType.Corner),
|
||||
Panel(panel_type=PanelType.EastWest),
|
||||
Panel(panel_type=PanelType.Corner),
|
||||
Panel(panel_type=PanelType.EastWest),
|
||||
Panel(panel_type=PanelType.EastWest),
|
||||
Panel(panel_type=PanelType.EastWest),
|
||||
Panel(panel_type=PanelType.Corner),
|
||||
Panel(panel_type=PanelType.NorthSouth),
|
||||
Panel(panel_type=PanelType.EastWest)]
|
||||
|
||||
counts = get_panel_type_counts(panels)
|
||||
|
||||
eq_(counts[PanelType.Corner], 5)
|
||||
eq_(counts[PanelType.NorthSouth], 2)
|
||||
eq_(counts[PanelType.EastWest], 7)
|
||||
eq_(counts[PanelType.Middle], 1)
|
||||
|
||||
67
test/helpers/csv_builder_test.py
Normal file
67
test/helpers/csv_builder_test.py
Normal file
@@ -0,0 +1,67 @@
|
||||
import unittest
|
||||
|
||||
from helix.csv_builder import CsvBuilder
|
||||
from nose.tools import eq_
|
||||
from numpy import array
|
||||
from helix.constants.panel_type import PanelType
|
||||
from helix.models.coordinate import Coordinate
|
||||
from helix.models.panel import Panel
|
||||
|
||||
|
||||
class CsvBuilderTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.subject = CsvBuilder()
|
||||
|
||||
def test_build_cad_output_correct_csv(self):
|
||||
panels = [
|
||||
Panel(handle='FOO', blockname='BAR', wind_zone=0, panel_type=PanelType.Corner, subarray=1, pressure=1.026,
|
||||
ballast=10, presented_link_tray=1, cross_tray=0, wind_anchors=0, id=10, original_coordinate=Coordinate(2, 3.0, rotation=4.00), seismic_anchors=0),
|
||||
Panel(handle='BAZ', blockname='QUX', wind_zone=2, panel_type=PanelType.Middle, subarray=1, pressure=3.033,
|
||||
ballast=3, presented_link_tray=0, cross_tray=1, wind_anchors=1, id=11, original_coordinate=Coordinate(1, 0.5, rotation=.25), seismic_anchors=1),
|
||||
Panel(handle='EGGS', blockname='SPAM', wind_zone=0, panel_type=PanelType.Corner, subarray=1, pressure=1.026,
|
||||
ballast=10, presented_link_tray=1, cross_tray=0, wind_anchors=0, id=12, original_coordinate=Coordinate(2, 3.0, rotation=4.00), seismic_anchors=2)
|
||||
]
|
||||
|
||||
expected_csv = "HANDLE\tBLOCKNAME\tWIND\tPOS\tSUBARRAY\tPSF\tBAL\tLTRAY\tXTRAY\tANC\tID\tXCOORD\tYCOORD\tANGLE\r\n" \
|
||||
"FOO\tBAR\tA\t1\t1\t1.03\t10\t1\t-\t-\t10\t2\t3.0\t4.0\r\n" \
|
||||
"BAZ\tQUX\tC\t4\t1\t3.03\t3\t-\t1\t1S\t11\t1\t0.5\t0.25\r\n" \
|
||||
"EGGS\tSPAM\tA\t1\t1\t1.03\t10\t1\t-\tSS\t12\t2\t3.0\t4.0\r\n"
|
||||
|
||||
eq_(self.subject.build_cad_output(panels), expected_csv)
|
||||
|
||||
def test_build_cad_output_correct_csv_with_fuzzy_wind_zone_if_exists(self):
|
||||
panels = [
|
||||
Panel(handle='FOO', blockname='BAR', wind_zone=0, panel_type=PanelType.Corner, subarray=1, pressure=1.026,
|
||||
ballast=10, presented_link_tray=1, cross_tray=0, wind_anchors=0, id=10, original_coordinate=Coordinate(2, 3.0, rotation=4.00), seismic_anchors=0),
|
||||
Panel(handle='BAZ', blockname='QUX', wind_zone=2, panel_type=PanelType.Middle, subarray=1, pressure=3.033,
|
||||
ballast=3, presented_link_tray=0, cross_tray=1, wind_anchors=1, id=11, original_coordinate=Coordinate(1, 0.5, rotation=.25), seismic_anchors=1,
|
||||
fuzzy_wind_zone=True),
|
||||
Panel(handle='EGGS', blockname='SPAM', wind_zone=0, panel_type=PanelType.Corner, subarray=1, pressure=1.026,
|
||||
ballast=10, presented_link_tray=1, cross_tray=0, wind_anchors=0, id=12, original_coordinate=Coordinate(2, 3.0, rotation=4.00), seismic_anchors=2,
|
||||
fuzzy_wind_zone=True)
|
||||
]
|
||||
|
||||
expected_csv = "HANDLE\tBLOCKNAME\tWIND\tPOS\tSUBARRAY\tPSF\tBAL\tLTRAY\tXTRAY\tANC\tID\tXCOORD\tYCOORD\tANGLE\tFUZZYWINDZONE\r\n" \
|
||||
"FOO\tBAR\tA\t1\t1\t1.03\t10\t1\t-\t-\t10\t2\t3.0\t4.0\t0\r\n" \
|
||||
"BAZ\tQUX\tC\t4\t1\t3.03\t3\t-\t1\t1S\t11\t1\t0.5\t0.25\t1\r\n" \
|
||||
"EGGS\tSPAM\tA\t1\t1\t1.03\t10\t1\t-\tSS\t12\t2\t3.0\t4.0\t1\r\n"
|
||||
|
||||
eq_(self.subject.build_cad_output(panels), expected_csv)
|
||||
|
||||
def test_build_bom_output_outputs_bom(self):
|
||||
expected_csv = "Part #\tDescription\tTotal\r\n6\tFoo\t404\r\n5\tBar\"\t503\r\n7\tBaz\t1337\r\n"
|
||||
|
||||
calculated_columns = array([[6, 'Foo', 404],
|
||||
[5, 'Bar"', 503],
|
||||
[7, 'Baz', 1337]])
|
||||
eq_(self.subject.build_bom_output(calculated_columns), expected_csv)
|
||||
|
||||
def test_build_cad_output_with_incomplete_input(self):
|
||||
panels = [
|
||||
Panel(subarray=1, id=1, original_coordinate=Coordinate(2, 3.0, rotation=4.00))
|
||||
]
|
||||
|
||||
expected_csv = "HANDLE\tBLOCKNAME\tWIND\tPOS\tSUBARRAY\tPSF\tBAL\tLTRAY\tXTRAY\tANC\tID\tXCOORD\tYCOORD\tANGLE\r\n" \
|
||||
"\t\t\t\t1\t\t\t-\t-\t-\t1\t2\t3.0\t4.0\r\n"
|
||||
|
||||
eq_(self.subject.build_cad_output(panels), expected_csv)
|
||||
558
test/helpers/doc_gen_params_builder_test.py
Normal file
558
test/helpers/doc_gen_params_builder_test.py
Normal file
@@ -0,0 +1,558 @@
|
||||
from collections import OrderedDict
|
||||
import os
|
||||
import unittest
|
||||
from unittest.mock import MagicMock
|
||||
from nose.tools import eq_
|
||||
from helix.constants.anchor_type import AnchorType
|
||||
from helix.constants.module_type import ModuleType
|
||||
from helix.constants.panel_type import PanelType
|
||||
from helix.constants.version import version
|
||||
|
||||
from helix.doc_gen_params_builder import DocGenParamsBuilder
|
||||
from helix.models.coordinate import Coordinate
|
||||
from helix.models.panel import Panel
|
||||
from helix.models.sql.inverters import Inverter
|
||||
from helix.models.sql.power_stations import PowerStation
|
||||
from helix.models.sql.sites import Site
|
||||
from helix.models.sql.standalone_inverters import StandaloneInverter
|
||||
from helix.models.subarray import Subarray
|
||||
from helix.user_values import UserValues
|
||||
|
||||
|
||||
class DocGenParamsBuilderTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.site = Site(system_type='1')
|
||||
|
||||
self.site.project_name = ''
|
||||
self.site.building_height = 0
|
||||
self.site.building_width = 0
|
||||
self.site.building_length = 0
|
||||
self.site.parapet_height = 0
|
||||
self.site.ballast_block_weight = 0
|
||||
self.site.max_psf = 0
|
||||
self.site.anchor_type = AnchorType.OMG_PowerGrip_Plus.value
|
||||
self.site.exposure_category = 'C'
|
||||
self.site.wind_speed = 0
|
||||
self.site.spectral_response = 1
|
||||
self.site.importance_factor = 1
|
||||
self.site.module_type = ModuleType.Cell96.value
|
||||
|
||||
self.user_values = UserValues(None, self.site)
|
||||
self.calculator = MagicMock()
|
||||
self.image_presenter = MagicMock()
|
||||
os.environ['SP_DOCGEN_API_KEY'] = 'TestDocGenApiKey'
|
||||
|
||||
def tearDown(self):
|
||||
os.environ['SP_DOCGEN_API_KEY'] = ''
|
||||
|
||||
def test_build_single_tilt(self):
|
||||
self.site.system_type = '0'
|
||||
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
|
||||
|
||||
self.calculator.L_B.return_value = 0.001
|
||||
self.calculator.k_z.return_value = 0.949932
|
||||
self.calculator.q_z.return_value = 0.12453
|
||||
self.calculator.get_computed_csv_columns.return_value = []
|
||||
self.calculator.documentation_summary_values.return_value = {'summary': 'foo'}
|
||||
self.calculator.summary_table.return_value = OrderedDict({PanelType.Corner:
|
||||
{'anchors': [1],
|
||||
'ballast blocks': [6],
|
||||
'pressure': ['4.46']}})
|
||||
self.calculator.minimum_array_sizes.return_value = [123]
|
||||
self.calculator.documentation_bom.return_value = []
|
||||
self.calculator.documentation_bom.return_value = [
|
||||
('88764', 9),
|
||||
('modules', 0)
|
||||
]
|
||||
self.image_presenter.generate_image.return_value = "".encode("utf-8")
|
||||
|
||||
params = subject.build()
|
||||
|
||||
expected = {
|
||||
'apiKey': 'TestDocGenApiKey',
|
||||
'templateName': 'Helix_Single_Tilt_Template',
|
||||
'nameValuePairs': [
|
||||
{'name': '1_a_anc', 'value': 1},
|
||||
{'name': '1_a_bb', 'value': 6},
|
||||
{'name': '1_a_psf', 'value': '4.46'},
|
||||
{'name': 'anchor_type', 'value': 'OMG PowerGrip Plus'},
|
||||
{'name': 'ballast_block_weight', 'value': 0.0},
|
||||
{'name': 'building_height', 'value': 0.0},
|
||||
{'name': 'building_length', 'value': 0.0},
|
||||
{'name': 'building_width', 'value': 0.0},
|
||||
{'name': 'exposure_category', 'value': 'C'},
|
||||
{'name': 'exposure_category_transition_distance', 'value': 0},
|
||||
{'name': 'kz', 'value': 0.95},
|
||||
{'name': 'lb', 'value': 0.0},
|
||||
{'name': 'max_allowable_system_pressure', 'value': 0.0},
|
||||
{'name': 'min_a', 'value': 123},
|
||||
{'name': 'module_type', 'value': '96 Cell'},
|
||||
{'name': 'parapet_height', 'value': 0.0},
|
||||
{'name': 'power_station_string', 'value': ''},
|
||||
{'name': 'project_name', 'value': ''},
|
||||
{'name': 'qz', 'value': 0.12},
|
||||
{'name': 'seismic_importance_factor', 'value': 1.0},
|
||||
{'name': 'spectral_response', 'value': 1.0},
|
||||
{'name': 'standalone_inverter_string', 'value': ''},
|
||||
{'name': 'subarrays_string', 'value': ''},
|
||||
{'name': 'summary', 'value': 'foo'},
|
||||
{'name': 'system_type', 'value': 'Single-Tilt'},
|
||||
{'name': 'total_88764', 'value': 9},
|
||||
{'name': 'total_modules', 'value': 0},
|
||||
{'name': 'version', 'value': version()},
|
||||
{'name': 'wind_speed', 'value': 0.0},
|
||||
],
|
||||
'dynamicImages': [
|
||||
{'imageKey': 'array_image', 'base64encodedImage': ''}
|
||||
]
|
||||
}
|
||||
|
||||
eq_(params, expected)
|
||||
|
||||
def test_build_dual_tilt(self):
|
||||
self.site.system_type = '1'
|
||||
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
|
||||
|
||||
self.calculator.L_B.return_value = 0
|
||||
self.calculator.k_z.return_value = 0
|
||||
self.calculator.q_z.return_value = 0
|
||||
self.calculator.get_computed_csv_columns.return_value = []
|
||||
self.calculator.documentation_summary_values.return_value = {'summary': 'foo'}
|
||||
self.image_presenter.generate_image.return_value = "".encode("utf-8")
|
||||
|
||||
params = subject.build()
|
||||
|
||||
eq_(sorted(params.keys()), ['apiKey', 'dynamicImages', 'nameValuePairs', 'templateName'])
|
||||
eq_(params['apiKey'], 'TestDocGenApiKey')
|
||||
eq_(params['templateName'], 'Helix_Dual_Tilt_Template')
|
||||
|
||||
def test_site_characterization(self):
|
||||
self.site.system_type = '0'
|
||||
self.site.project_name = 'Test Project Name'
|
||||
self.site.building_height = 100
|
||||
self.site.building_width = 1000
|
||||
self.site.building_length = 1500
|
||||
self.site.parapet_height = 0
|
||||
self.site.ballast_block_weight = 20
|
||||
self.site.max_psf = 17
|
||||
self.site.anchor_type = AnchorType.EcoFasten.value
|
||||
self.site.exposure_category = 'D'
|
||||
self.site.wind_speed = 110
|
||||
self.site.spectral_response = 1
|
||||
self.site.importance_factor = 1
|
||||
self.site.module_type = ModuleType.Cell96.value
|
||||
|
||||
self.calculator.L_B.return_value = 23
|
||||
self.calculator.k_z.return_value = 34
|
||||
self.calculator.q_z.return_value = 45
|
||||
self.calculator.get_computed_csv_columns.return_value = [
|
||||
Panel(),
|
||||
Panel()
|
||||
]
|
||||
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
|
||||
|
||||
expected_site_characterization = {
|
||||
'project_name': 'Test Project Name',
|
||||
'building_height': 100.0,
|
||||
'building_width': 1000.0,
|
||||
'building_length': 1500.0,
|
||||
'parapet_height': 0.0,
|
||||
'ballast_block_weight': 20.0,
|
||||
'max_allowable_system_pressure': 17,
|
||||
'anchor_type': 'EcoFasten Eco 65',
|
||||
'exposure_category': 'D',
|
||||
'exposure_category_transition_distance': 0,
|
||||
'wind_speed': 110,
|
||||
'spectral_response': 1,
|
||||
'seismic_importance_factor': 1,
|
||||
'module_type': '96 Cell',
|
||||
'system_type': 'Single-Tilt',
|
||||
|
||||
'total_modules': 2,
|
||||
'version': version(),
|
||||
'lb': 23,
|
||||
'kz': 34,
|
||||
'qz': 45
|
||||
}
|
||||
|
||||
eq_(subject.site_characterization(), expected_site_characterization)
|
||||
|
||||
def test_build_panel_attributes_dual_tilt(self):
|
||||
self.site.system_type = '1'
|
||||
self.calculator.summary_table.return_value = OrderedDict({
|
||||
PanelType.Corner:
|
||||
{'anchors': [1, 1, 0, 0, 0],
|
||||
'ballast blocks': [6, 0, 13, 5, 0],
|
||||
'pressure': ['4.46', '2.40', '6.86', '4.08', '2.40']},
|
||||
PanelType.NorthSouth:
|
||||
{'anchors': [1, 0, 0, 0, 0],
|
||||
'ballast blocks': [0, 19, 9, 3, 0],
|
||||
'pressure': ['2.40', '8.94', '5.47', '3.41', '2.40']},
|
||||
PanelType.EastWest:
|
||||
{'anchors': [1, 0, 0, 0, 0],
|
||||
'ballast blocks': [0, 19, 9, 3, 0],
|
||||
'pressure': ['2.26', '8.77', '5.35', '3.27', '2.26']},
|
||||
PanelType.Middle:
|
||||
{'anchors': [0, 0, 0, 0, 0],
|
||||
'ballast blocks': [16, 8, 3, 0, 0],
|
||||
'pressure': ['7.76', '5.01', '3.27', '2.26', '2.26']}
|
||||
})
|
||||
|
||||
self.calculator.minimum_array_sizes.return_value = [22, 19, 23, 19, 6]
|
||||
|
||||
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
|
||||
|
||||
expected = {
|
||||
'1_a_bb': 6,
|
||||
'1_b_bb': 0,
|
||||
'1_c_bb': 13,
|
||||
'1_d_bb': 5,
|
||||
'1_e_bb': 0,
|
||||
|
||||
'1_a_anc': 1,
|
||||
'1_b_anc': 1,
|
||||
'1_c_anc': 0,
|
||||
'1_d_anc': 0,
|
||||
'1_e_anc': 0,
|
||||
|
||||
'1_a_psf': '4.46',
|
||||
'1_b_psf': '2.40',
|
||||
'1_c_psf': '6.86',
|
||||
'1_d_psf': '4.08',
|
||||
'1_e_psf': '2.40',
|
||||
|
||||
'2_a_bb': 0,
|
||||
'2_b_bb': 19,
|
||||
'2_c_bb': 9,
|
||||
'2_d_bb': 3,
|
||||
'2_e_bb': 0,
|
||||
|
||||
'2_a_anc': 1,
|
||||
'2_b_anc': 0,
|
||||
'2_c_anc': 0,
|
||||
'2_d_anc': 0,
|
||||
'2_e_anc': 0,
|
||||
|
||||
'2_a_psf': '2.40',
|
||||
'2_b_psf': '8.94',
|
||||
'2_c_psf': '5.47',
|
||||
'2_d_psf': '3.41',
|
||||
'2_e_psf': '2.40',
|
||||
|
||||
'3_a_bb': 0,
|
||||
'3_b_bb': 19,
|
||||
'3_c_bb': 9,
|
||||
'3_d_bb': 3,
|
||||
'3_e_bb': 0,
|
||||
|
||||
'3_a_anc': 1,
|
||||
'3_b_anc': 0,
|
||||
'3_c_anc': 0,
|
||||
'3_d_anc': 0,
|
||||
'3_e_anc': 0,
|
||||
|
||||
'3_a_psf': '2.26',
|
||||
'3_b_psf': '8.77',
|
||||
'3_c_psf': '5.35',
|
||||
'3_d_psf': '3.27',
|
||||
'3_e_psf': '2.26',
|
||||
|
||||
'4_a_bb': 16,
|
||||
'4_b_bb': 8,
|
||||
'4_c_bb': 3,
|
||||
'4_d_bb': 0,
|
||||
'4_e_bb': 0,
|
||||
|
||||
'4_a_anc': 0,
|
||||
'4_b_anc': 0,
|
||||
'4_c_anc': 0,
|
||||
'4_d_anc': 0,
|
||||
'4_e_anc': 0,
|
||||
|
||||
'4_a_psf': '7.76',
|
||||
'4_b_psf': '5.01',
|
||||
'4_c_psf': '3.27',
|
||||
'4_d_psf': '2.26',
|
||||
'4_e_psf': '2.26',
|
||||
|
||||
'min_a': 22,
|
||||
'min_b': 19,
|
||||
'min_c': 23,
|
||||
'min_d': 19,
|
||||
'min_e': 6
|
||||
}
|
||||
|
||||
eq_(subject.panel_attributes(), expected)
|
||||
|
||||
def test_build_bom(self):
|
||||
self.calculator.documentation_bom.return_value = [
|
||||
('512200', 480),
|
||||
('513832', 0),
|
||||
('513833', 790),
|
||||
('513836', 0),
|
||||
('513841', 196),
|
||||
|
||||
('anchors', 262),
|
||||
('ballast', 6786),
|
||||
('modules', 1726)
|
||||
]
|
||||
|
||||
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
|
||||
|
||||
expected = {
|
||||
'total_512200': 480,
|
||||
'total_513832': 0,
|
||||
'total_513833': 790,
|
||||
'total_513836': 0,
|
||||
'total_513841': 196,
|
||||
'total_anchors': 262,
|
||||
'total_ballast': 6786,
|
||||
'total_modules': 1726
|
||||
}
|
||||
|
||||
eq_(subject.bom(), expected)
|
||||
|
||||
def test_build_power_station(self):
|
||||
power_station_1 = PowerStation(
|
||||
description='1',
|
||||
quantity=1,
|
||||
ac_run_length=55,
|
||||
inverters=[
|
||||
Inverter(
|
||||
model='4',
|
||||
strings_per_inverter=2,
|
||||
sunshade=True,
|
||||
dc_switch=False
|
||||
),
|
||||
Inverter(
|
||||
model='5',
|
||||
strings_per_inverter=5,
|
||||
sunshade=False,
|
||||
dc_switch=False
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
power_station_2 = PowerStation(
|
||||
description='2',
|
||||
quantity=3,
|
||||
ac_run_length=89,
|
||||
inverters=[
|
||||
Inverter(
|
||||
model='6',
|
||||
strings_per_inverter=6,
|
||||
sunshade=False,
|
||||
dc_switch=True
|
||||
),
|
||||
Inverter(
|
||||
model='8',
|
||||
strings_per_inverter=8,
|
||||
sunshade=False,
|
||||
dc_switch=False
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
self.site.power_stations = [power_station_1, power_station_2]
|
||||
|
||||
expected = {
|
||||
'power_station_string': """
|
||||
Description: 1
|
||||
\tQuantity: 1
|
||||
\tAC Run Length: 55
|
||||
\tInverters:
|
||||
\t\tModel: 12kW SMA Tripower - 514686
|
||||
\t\tStrings per inverter: 2
|
||||
\t\tSunShade: Yes
|
||||
|
||||
\t\tModel: 15kW SMA Tripower - 514687
|
||||
\t\tStrings per inverter: 5
|
||||
|
||||
Description: 2
|
||||
\tQuantity: 3
|
||||
\tAC Run Length: 89
|
||||
\tInverters:
|
||||
\t\tModel: 20kW SMA Tripower - 512676
|
||||
\t\tStrings per inverter: 6
|
||||
\t\tDC Switch: Yes
|
||||
|
||||
\t\tModel: 24kW SMA Tripower - 514685
|
||||
\t\tStrings per inverter: 8
|
||||
|
||||
"""
|
||||
}
|
||||
|
||||
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
|
||||
eq_(subject.power_stations(), expected)
|
||||
|
||||
def test_standalone_inverters(self):
|
||||
power_station = PowerStation(
|
||||
description='My Power Station',
|
||||
quantity=1,
|
||||
ac_run_length=45,
|
||||
inverters=[
|
||||
Inverter(
|
||||
model='8',
|
||||
strings_per_inverter=7,
|
||||
sunshade=True,
|
||||
dc_switch=True
|
||||
),
|
||||
Inverter(
|
||||
model='4',
|
||||
strings_per_inverter=2,
|
||||
sunshade=False,
|
||||
dc_switch=False
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
standalone_inverter_1 = StandaloneInverter(
|
||||
inverter=[Inverter(model='6', strings_per_inverter='5', sunshade=True, dc_switch=False)],
|
||||
ac_run_length=45,
|
||||
attachment_point=power_station,
|
||||
)
|
||||
|
||||
standalone_inverter_2 = StandaloneInverter(
|
||||
inverter=[Inverter(model='4', strings_per_inverter='3', sunshade=False, dc_switch=True)],
|
||||
ac_run_length=45,
|
||||
attachment_point=None,
|
||||
)
|
||||
|
||||
self.site.power_stations = [power_station]
|
||||
self.site.standalone_inverters = [standalone_inverter_1, standalone_inverter_2]
|
||||
|
||||
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
|
||||
"""
|
||||
AC Run Length: 3
|
||||
Attachment Point: Switch Gear
|
||||
Model: 20kW SMA Tripower - 512676
|
||||
Strings per inverter: 6
|
||||
Sunshade: Yes
|
||||
DC Switch: Yes
|
||||
"""
|
||||
|
||||
expected = {
|
||||
'standalone_inverter_string': """
|
||||
\tAC Run Length: 45
|
||||
\tAttachment Point: My Power Station
|
||||
\tModel: 20kW SMA Tripower - 512676
|
||||
\tStrings per inverter: 5
|
||||
\tSunShade: Yes
|
||||
|
||||
\tAC Run Length: 45
|
||||
\tAttachment Point: Switch Gear
|
||||
\tModel: 12kW SMA Tripower - 514686
|
||||
\tStrings per inverter: 3
|
||||
\tDC Switch: Yes
|
||||
"""
|
||||
}
|
||||
eq_(subject.standalone_inverters(), expected)
|
||||
|
||||
def test_subarray_summary(self):
|
||||
self.calculator.subarray_summary.return_value = [
|
||||
Subarray(subarray_number=1, origin=Coordinate(0, 0), required_seismic_anchors=11, weight=23782.67, start_row=0,
|
||||
size=192),
|
||||
Subarray(subarray_number=2, origin=Coordinate(0, 0), required_seismic_anchors=0, weight=13113.05,
|
||||
start_row=192, size=96)
|
||||
]
|
||||
|
||||
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
|
||||
|
||||
expected = {
|
||||
'subarrays_string': """
|
||||
\tSubarray: 1
|
||||
\tSeismic Anchors: 11
|
||||
\tWeight: 23,783 lbs
|
||||
|
||||
\tSubarray: 2
|
||||
\tSeismic Anchors: 0
|
||||
\tWeight: 13,113 lbs
|
||||
"""
|
||||
}
|
||||
eq_(subject.subarray_summary(), expected)
|
||||
|
||||
def test_array_image(self):
|
||||
panels = [
|
||||
Panel(id=1)
|
||||
]
|
||||
subarrays = [
|
||||
Subarray(subarray_number=1)
|
||||
]
|
||||
self.calculator.get_computed_csv_columns.return_value = panels
|
||||
self.calculator.subarrays = subarrays
|
||||
self.image_presenter.generate_image.return_value = "hello world".encode("utf-8")
|
||||
|
||||
subject = DocGenParamsBuilder(self.user_values, self.user_values.system_type(), self.calculator, self.image_presenter)
|
||||
|
||||
expected = {'array_image': 'aGVsbG8gd29ybGQ='}
|
||||
|
||||
eq_(subject.array_image(), expected)
|
||||
|
||||
self.image_presenter.generate_image.assert_called_once_with(panels, subarrays)
|
||||
|
||||
def test_convert_list_params_to_dict(self):
|
||||
list_params = [
|
||||
{
|
||||
'name': 'foo',
|
||||
'value': 'bar'
|
||||
},
|
||||
{
|
||||
'name': 'cat',
|
||||
'value': 'dog'
|
||||
}
|
||||
]
|
||||
|
||||
expected = {
|
||||
'foo': 'bar',
|
||||
'cat': 'dog'
|
||||
}
|
||||
|
||||
eq_(DocGenParamsBuilder.convert_list_params_to_dict(list_params), expected)
|
||||
|
||||
def test_convert_dict_params_to_list(self):
|
||||
dict_params = {
|
||||
'foo': 'bar',
|
||||
'cat': 'dog',
|
||||
'fast': 'slow',
|
||||
}
|
||||
|
||||
expected = sorted([
|
||||
{
|
||||
'name': 'foo',
|
||||
'value': 'bar'
|
||||
},
|
||||
{
|
||||
'name': 'cat',
|
||||
'value': 'dog'
|
||||
},
|
||||
{
|
||||
'name': 'fast',
|
||||
'value': 'slow'
|
||||
}
|
||||
], key=lambda k: k['name'])
|
||||
|
||||
eq_(DocGenParamsBuilder.convert_dict_params_to_list(dict_params), expected)
|
||||
|
||||
def test_convert_dict_parms_to_list_other_names(self):
|
||||
dict_params = {
|
||||
'foo': 'bar',
|
||||
'cat': 'dog',
|
||||
'fast': 'slow',
|
||||
}
|
||||
|
||||
expected = sorted([
|
||||
{
|
||||
'baz': 'foo',
|
||||
'qux': 'bar'
|
||||
},
|
||||
{
|
||||
'baz': 'cat',
|
||||
'qux': 'dog'
|
||||
},
|
||||
{
|
||||
'baz': 'fast',
|
||||
'qux': 'slow'
|
||||
}
|
||||
], key=lambda k: k['baz'])
|
||||
|
||||
eq_(DocGenParamsBuilder.convert_dict_params_to_list(dict_params, key_name='baz', value_name='qux'), expected)
|
||||
946
test/helpers/dxf_helper_test.py
Normal file
946
test/helpers/dxf_helper_test.py
Normal file
@@ -0,0 +1,946 @@
|
||||
from math import pi, cos, sin
|
||||
import unittest
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from nose.tools import eq_
|
||||
|
||||
from helix.Services.dxf_helper import DXFHelper
|
||||
from helix.constants.module_type_constants.dual_tilt_96_cell_constants import DualTilt96CellConstants
|
||||
from helix.constants.panel_type import PanelType
|
||||
from helix.constants.system_type import SystemType
|
||||
from helix.models.coordinate import Coordinate
|
||||
from helix.models.dxf.dxf_error import DXFError
|
||||
from helix.models.dxf.graph_direction import GraphDirection
|
||||
from helix.models.dxf.graph_node import GraphNode
|
||||
from helix.models.dxf.polygon import Polygon
|
||||
from helix.models.panel import Panel
|
||||
from helix.models.subarray import Subarray
|
||||
|
||||
|
||||
class DXFHelperTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.subject = DXFHelper()
|
||||
|
||||
def test_generate_panels(self):
|
||||
modules = [
|
||||
Polygon(points=[(-2319.403, 687.080), (-2367.852, 648.146), (-2397.356, 684.863), (-2348.907, 723.792)]),
|
||||
Polygon(points=[(-2270.9747, 726.000), (-2319.419, 687.063), (-2348.923, 723.780), (-2300.478, 762.709)])
|
||||
]
|
||||
|
||||
translated_modules = [
|
||||
Polygon(points=[(77.953, 38.933), (29.504, 0.0), (0.0, 36.717), (48.449, 75.646)]),
|
||||
Polygon(points=[(126.382, 77.850), (77.937, 38.917), (48.433, 75.634), (96.878, 114.563)])
|
||||
]
|
||||
|
||||
panels = self.subject.generate_panels(modules, translated_modules)
|
||||
|
||||
expected = [
|
||||
Panel(id=1, coordinate=Coordinate(38.977, 37.824, 38.78204144530477), original_coordinate=Coordinate(-2358.3795, 685.970, 38.78204144530477)),
|
||||
Panel(id=2, coordinate=Coordinate(87.407, 76.741, 38.78435126730565), original_coordinate=Coordinate(-2309.949, 724.888, 38.78435126730565))
|
||||
]
|
||||
|
||||
eq_(panels, expected)
|
||||
|
||||
def test_should_consolidate_modules_returns_false_for_single_tilt(self):
|
||||
eq_(self.subject.should_consolidate_modules(None, SystemType.singleTilt, None), False)
|
||||
|
||||
def test_should_consolidate_modules_returns_true_for_dual_tilt_that_are_not_consolidated(self):
|
||||
modules = [
|
||||
Polygon(points=[(-5.17655, -38.8958), (-7.73719, -34.4719), (-4.81221, -32.7789), (-2.25157, -37.2028)]),
|
||||
Polygon(points=[(-2.25157, -37.2028), (-5.17655, -38.8958), (1.04417, -35.2963), (-1.88081, -36.9894)]),
|
||||
]
|
||||
eq_(self.subject.should_consolidate_modules(modules, SystemType.dualTilt, DualTilt96CellConstants()), True)
|
||||
|
||||
def test_should_consolidate_modules_returns_false_for_dual_tilt_that_are_consolidated(self):
|
||||
modules = [
|
||||
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (103.732, 38.937), (55.28, 0.0)]),
|
||||
]
|
||||
eq_(self.subject.should_consolidate_modules(modules, SystemType.dualTilt, DualTilt96CellConstants()), False)
|
||||
|
||||
def test_consolidate_dual_tilt_modules(self):
|
||||
modules = [
|
||||
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (76.091, 73.338), (27.634, 34.401)]),
|
||||
Polygon(points=[(103.732, 38.937), (55.28, 0.0), (27.642, 34.393), (76.098, 73.331)]),
|
||||
]
|
||||
|
||||
expected_modules = [
|
||||
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (103.732, 38.937), (55.28, 0.0)]),
|
||||
]
|
||||
module_format = None
|
||||
panels = self.subject.consolidate_dual_tilt_modules(modules,
|
||||
SystemType.dualTilt,
|
||||
module_format)
|
||||
|
||||
eq_(panels, expected_modules)
|
||||
|
||||
def test_consolidate_dual_tilt_modules_does_nothing_if_given_single_tilt_modules(self):
|
||||
modules = [
|
||||
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (76.091, 73.338), (27.634, 34.401)]),
|
||||
Polygon(points=[(103.732, 38.937), (55.28, 0.0), (27.642, 34.393), (76.098, 73.331)]),
|
||||
]
|
||||
|
||||
expected_modules = [
|
||||
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (76.091, 73.338), (27.634, 34.401)]),
|
||||
Polygon(points=[(103.732, 38.937), (55.28, 0.0), (27.642, 34.393), (76.098, 73.331)]),
|
||||
]
|
||||
module_format = None
|
||||
panels = self.subject.consolidate_dual_tilt_modules(modules,
|
||||
SystemType.singleTilt,
|
||||
module_format)
|
||||
|
||||
eq_(panels, expected_modules)
|
||||
|
||||
def test_consolidates_dual_tilt_modules_throws_if_given_dual_tilt_but_unpairable_modules(self):
|
||||
modules = [
|
||||
Polygon(points=[(0.0, 68.795), (48.453, 107.732), (76.091, 73.338), (27.634, 34.401)]),
|
||||
Polygon(points=[(1103.732, 38.937), (155.28, 0.0), (127.642, 34.393), (176.098, 73.331)]),
|
||||
]
|
||||
|
||||
try:
|
||||
module_format = None
|
||||
self.subject.consolidate_dual_tilt_modules(modules,
|
||||
SystemType.dualTilt,
|
||||
module_format)
|
||||
assert False
|
||||
except DXFError as error:
|
||||
eq_(error.message, "Error - not a dual tilt file, or invalid dual tilt design.")
|
||||
|
||||
def test_generate_polygons(self):
|
||||
lines = [
|
||||
MagicMock(start=(-589.128, 174.518), end=(-601.434, 164.629)),
|
||||
MagicMock(start=(-601.434, 164.629), end=(-608.928, 173.955)),
|
||||
MagicMock(start=(-608.928, 173.955), end=(-596.622, 183.843)),
|
||||
MagicMock(start=(-596.622, 183.843), end=(-589.128, 174.518))
|
||||
]
|
||||
polygons = self.subject.generate_polygons(lines)
|
||||
|
||||
expected = [Polygon(points=[(-589.128, 174.518), (-601.434, 164.629), (-608.928, 173.955), (-596.622, 183.843)])]
|
||||
eq_(polygons, expected)
|
||||
|
||||
def test_generate_polygons_seperate_point(self):
|
||||
lines = [
|
||||
MagicMock(start=(-589.128, 174.518), end=(-601.434, 164.629)),
|
||||
MagicMock(start=(-601.434, 164.629), end=(-608.928, 173.955)),
|
||||
MagicMock(start=(1, 2), end=(3, 4)),
|
||||
MagicMock(start=(-608.928, 173.955), end=(-596.622, 183.843)),
|
||||
MagicMock(start=(-596.622, 183.843), end=(-589.128, 174.518))
|
||||
]
|
||||
polygons = self.subject.generate_polygons(lines)
|
||||
|
||||
expected = [
|
||||
Polygon(points=[(-589.128, 174.518), (-601.434, 164.629), (-608.928, 173.955)]),
|
||||
Polygon(points=[(1, 2), (3, 4)]),
|
||||
Polygon(points=[(-608.928, 173.955), (-596.622, 183.843), (-589.128, 174.518)])
|
||||
]
|
||||
|
||||
eq_(polygons, expected)
|
||||
|
||||
def test_build_polygons(self):
|
||||
entities = [
|
||||
MagicMock(layer='Modules', start=(-589.128, 174.518), end=(-601.434, 164.629)),
|
||||
MagicMock(layer='Modules', start=(-601.434, 164.629), end=(-608.928, 173.955)),
|
||||
MagicMock(layer='Modules', start=(-608.928, 173.955), end=(-596.622, 183.843)),
|
||||
MagicMock(layer='Modules', start=(-596.622, 183.843), end=(-589.128, 174.518)),
|
||||
MagicMock(layer='Buildings', start=(-576.827, 184.403), end=(-589.132, 174.514)),
|
||||
MagicMock(layer='Buildings', start=(-589.132, 174.514), end=(-596.626, 183.84)),
|
||||
MagicMock(layer='Buildings', start=(-596.626, 183.84), end=(-584.321, 193.728)),
|
||||
MagicMock(layer='Buildings', start=(-584.321, 193.728), end=(-576.827, 184.403)),
|
||||
]
|
||||
|
||||
polygons = self.subject.build_polygons(entities)
|
||||
|
||||
inches_per_feet = 12
|
||||
buildings = [Polygon(points=[(inches_per_feet * -576.827, inches_per_feet * 184.403), (inches_per_feet * -589.132, inches_per_feet * 174.514), (inches_per_feet * -596.626, inches_per_feet * 183.84), (inches_per_feet * -584.321, inches_per_feet * 193.728)])]
|
||||
modules = [Polygon(points=[(inches_per_feet * -589.128, inches_per_feet * 174.518), (inches_per_feet * -601.434, inches_per_feet * 164.629), (inches_per_feet * -608.928, inches_per_feet * 173.955), (inches_per_feet * -596.622, inches_per_feet * 183.843)])]
|
||||
|
||||
expected = (buildings, modules)
|
||||
|
||||
eq_(polygons, expected)
|
||||
|
||||
def test_translate_towards_origin(self):
|
||||
buildings = [Polygon(points=[(-576.827, 184.403), (-589.132, 174.514), (-596.626, 183.84), (-584.321, 193.728)])]
|
||||
modules = [Polygon(points=[(-589.128, 174.518), (-601.434, 164.629), (-608.928, 173.955), (-596.622, 183.843)])]
|
||||
|
||||
expected_buildings = [Polygon(points=[(32.101, 19.774), (19.796, 9.885), (12.302, 19.211), (24.607, 29.099)])]
|
||||
expected_modules = [Polygon(points=[(19.8, 9.889), (7.494, 0), (0, 9.326), (12.306, 19.214)])]
|
||||
|
||||
eq_(self.subject.translate_towards_origin(buildings, modules), (expected_buildings, expected_modules))
|
||||
|
||||
def test_get_polygons_counterclockwise(self):
|
||||
|
||||
polygons = [Polygon(points=[(0, 0), (0, 1), (1, 1), (1, 0)]),
|
||||
Polygon(points=[(0, 0), (0, 2), (2, 2), (2, 0)]),
|
||||
Polygon(points=[(0, 0), (2, 0), (2, 2), (0, 2)])]
|
||||
|
||||
expected_polygons = [Polygon(points=[(1, 0), (1, 1), (0, 1), (0, 0)]),
|
||||
Polygon(points=[(2, 0), (2, 2), (0, 2), (0, 0)]),
|
||||
Polygon(points=[(0, 0), (2, 0), (2, 2), (0, 2)])]
|
||||
|
||||
eq_(self.subject.get_polygons_counterclockwise(polygons), expected_polygons)
|
||||
|
||||
def test_build_node_graph(self):
|
||||
panels = [
|
||||
Panel(coordinate=Coordinate(10, 0, rotation=0)),
|
||||
Panel(coordinate=Coordinate(20, 0, rotation=0)),
|
||||
Panel(coordinate=Coordinate(10, 20, rotation=0)),
|
||||
Panel(coordinate=Coordinate(20, 20, rotation=0))
|
||||
]
|
||||
node_graph = self.subject.build_node_graph(panels, (10, 10))
|
||||
|
||||
node_a = GraphNode(Panel(coordinate=Coordinate(10, 0, rotation=0)), 10, 10)
|
||||
node_b = GraphNode(Panel(coordinate=Coordinate(20, 0, rotation=0)), 10, 10)
|
||||
node_c = GraphNode(Panel(coordinate=Coordinate(10, 20, rotation=0)), 10, 10)
|
||||
node_d = GraphNode(Panel(coordinate=Coordinate(20, 20, rotation=0)), 10, 10)
|
||||
|
||||
node_a.add_neighbor(node_b, GraphDirection.East)
|
||||
node_c.add_neighbor(node_d, GraphDirection.East)
|
||||
|
||||
expected = [node_a, node_b, node_c, node_d]
|
||||
eq_(node_graph, expected)
|
||||
|
||||
def test_build_node_graph_weird_case(self):
|
||||
panels = [
|
||||
Panel(coordinate=Coordinate(38.04431188249998, 857.508730771, -51.21962134154259)),
|
||||
Panel(coordinate=Coordinate(86.50299946749976, 896.449696681, -51.21563589970276))
|
||||
]
|
||||
|
||||
node_graph = self.subject.build_node_graph(panels, (88.24, 62.16))
|
||||
|
||||
node_a = GraphNode(Panel(coordinate=Coordinate(38.04431188249998, 857.508730771, -51.21962134154259)), 88.24, 62.16)
|
||||
node_b = GraphNode(Panel(coordinate=Coordinate(86.50299946749976, 896.449696681, -51.21563589970276)), 88.24, 62.16)
|
||||
|
||||
node_a.add_neighbor(node_b, GraphDirection.North)
|
||||
|
||||
eq_(node_graph, [node_a, node_b])
|
||||
|
||||
def test_build_node_graph_throws_dxf_validation_error_if_there_are_panels_with_no_neighbors(self):
|
||||
panels = [
|
||||
Panel(coordinate=Coordinate(10, 0, rotation=0)),
|
||||
Panel(coordinate=Coordinate(20, 0, rotation=0)),
|
||||
Panel(coordinate=Coordinate(100, 200, rotation=0))
|
||||
]
|
||||
try:
|
||||
self.subject.build_node_graph(panels, (10, 10))
|
||||
assert False
|
||||
except DXFError as error:
|
||||
eq_(error.message, "Error - invalid module spacing. Please check to make sure the correct system type and panel spacing are present")
|
||||
|
||||
def test_detect_subarrays(self):
|
||||
node_a = GraphNode(Panel(coordinate=Coordinate(1, 0, rotation=0)), 1, 1)
|
||||
node_b = GraphNode(Panel(coordinate=Coordinate(2, 0, rotation=0)), 1, 1)
|
||||
node_c = GraphNode(Panel(coordinate=Coordinate(1, 2, rotation=0)), 1, 1)
|
||||
|
||||
node_a.add_neighbor(node_b, GraphDirection.East)
|
||||
|
||||
nodes = [node_a, node_b, node_c]
|
||||
panels = [node.panel for node in nodes]
|
||||
|
||||
subarrays = self.subject.detect_subarrays(nodes, panels)
|
||||
expected = [
|
||||
Subarray(subarray_number=1, start_row=0, size=2),
|
||||
Subarray(subarray_number=2, start_row=2, size=1)
|
||||
]
|
||||
|
||||
eq_(subarrays, expected)
|
||||
|
||||
def test_throws_dxf_validation_error_if_blows_stack_during_subarray_detection(self):
|
||||
nodes = []
|
||||
for i in range(3000):
|
||||
nodes.append(GraphNode(Panel(coordinate=Coordinate(i, 0)), i, 0))
|
||||
|
||||
for i in range(1, 3000):
|
||||
node_a = nodes[i - 1]
|
||||
node = nodes[i]
|
||||
node.add_neighbor(node_a, GraphDirection.East)
|
||||
|
||||
panels = [node.panel for node in nodes]
|
||||
try:
|
||||
subarrays = self.subject.detect_subarrays(nodes, panels)
|
||||
eq_(len(subarrays), 0)
|
||||
except DXFError as error:
|
||||
eq_(error.message, "Array size is too big. Max is 150' by 150'.")
|
||||
|
||||
def test_detect_panel_types(self):
|
||||
node_0_0 = GraphNode(Panel(coordinate=Coordinate(0, 0, rotation=0)), 1, 1)
|
||||
node_1_0 = GraphNode(Panel(coordinate=Coordinate(1, 0, rotation=0)), 1, 1)
|
||||
node_2_0 = GraphNode(Panel(coordinate=Coordinate(2, 0, rotation=0)), 1, 1)
|
||||
node_3_0 = GraphNode(Panel(coordinate=Coordinate(3, 0, rotation=0)), 1, 1)
|
||||
|
||||
node_0_1 = GraphNode(Panel(coordinate=Coordinate(0, 1, rotation=0)), 1, 1)
|
||||
node_1_1 = GraphNode(Panel(coordinate=Coordinate(1, 1, rotation=0)), 1, 1)
|
||||
node_2_1 = GraphNode(Panel(coordinate=Coordinate(2, 1, rotation=0)), 1, 1)
|
||||
node_3_1 = GraphNode(Panel(coordinate=Coordinate(3, 1, rotation=0)), 1, 1)
|
||||
|
||||
node_0_2 = GraphNode(Panel(coordinate=Coordinate(0, 2, rotation=0)), 1, 1)
|
||||
node_1_2 = GraphNode(Panel(coordinate=Coordinate(1, 2, rotation=0)), 1, 1)
|
||||
node_2_2 = GraphNode(Panel(coordinate=Coordinate(2, 2, rotation=0)), 1, 1)
|
||||
|
||||
node_0_0.add_neighbor(node_0_1, GraphDirection.North)
|
||||
node_0_0.add_neighbor(node_1_1, GraphDirection.NorthEast)
|
||||
node_0_0.add_neighbor(node_1_0, GraphDirection.East)
|
||||
|
||||
node_2_0.add_neighbor(node_1_0, GraphDirection.West)
|
||||
node_2_0.add_neighbor(node_1_1, GraphDirection.NorthWest)
|
||||
node_2_0.add_neighbor(node_2_1, GraphDirection.North)
|
||||
node_2_0.add_neighbor(node_3_1, GraphDirection.NorthEast)
|
||||
node_2_0.add_neighbor(node_3_0, GraphDirection.East)
|
||||
|
||||
node_1_1.add_neighbor(node_0_1, GraphDirection.West)
|
||||
node_1_1.add_neighbor(node_1_0, GraphDirection.South)
|
||||
node_1_1.add_neighbor(node_1_2, GraphDirection.North)
|
||||
node_1_1.add_neighbor(node_2_1, GraphDirection.East)
|
||||
|
||||
node_3_1.add_neighbor(node_2_1, GraphDirection.West)
|
||||
|
||||
node_0_2.add_neighbor(node_0_1, GraphDirection.South)
|
||||
node_0_2.add_neighbor(node_1_1, GraphDirection.SouthEast)
|
||||
node_0_2.add_neighbor(node_1_2, GraphDirection.East)
|
||||
|
||||
node_2_2.add_neighbor(node_1_2, GraphDirection.West)
|
||||
node_2_2.add_neighbor(node_1_1, GraphDirection.SouthWest)
|
||||
node_2_2.add_neighbor(node_2_1, GraphDirection.South)
|
||||
node_2_2.add_neighbor(node_3_1, GraphDirection.SouthEast)
|
||||
|
||||
nodes = [
|
||||
node_0_0,
|
||||
node_1_0,
|
||||
node_2_0,
|
||||
node_3_0,
|
||||
node_0_1,
|
||||
node_1_1,
|
||||
node_2_1,
|
||||
node_3_1,
|
||||
node_0_2,
|
||||
node_1_2,
|
||||
node_2_2
|
||||
]
|
||||
|
||||
self.subject.detect_panel_types(nodes)
|
||||
|
||||
def assert_has_type(node, panel_type):
|
||||
eq_(node.panel.panel_type, panel_type)
|
||||
|
||||
assert_has_type(node_0_0, PanelType.Corner)
|
||||
assert_has_type(node_1_0, PanelType.NorthSouth)
|
||||
assert_has_type(node_2_0, PanelType.NorthSouth)
|
||||
assert_has_type(node_3_0, PanelType.Corner)
|
||||
assert_has_type(node_0_1, PanelType.EastWest)
|
||||
assert_has_type(node_1_1, PanelType.Middle)
|
||||
assert_has_type(node_2_1, PanelType.Middle)
|
||||
assert_has_type(node_3_1, PanelType.Corner)
|
||||
assert_has_type(node_0_2, PanelType.Corner)
|
||||
assert_has_type(node_1_2, PanelType.NorthSouth)
|
||||
assert_has_type(node_2_2, PanelType.Corner)
|
||||
|
||||
def test_detect_dual_tilt_wind_zones_simple_rectangle_mid_lb(self):
|
||||
system_type = SystemType.dualTilt
|
||||
|
||||
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
|
||||
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
|
||||
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
|
||||
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
|
||||
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
|
||||
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
|
||||
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
|
||||
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
|
||||
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
|
||||
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
|
||||
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
|
||||
|
||||
panels = [
|
||||
panel_0_2, panel_1_2, panel_2_2,
|
||||
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
|
||||
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
|
||||
]
|
||||
|
||||
sorted_panels = sorted(panels, key=lambda x: x.id)
|
||||
|
||||
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
|
||||
|
||||
buildings = [
|
||||
Polygon(points=[
|
||||
(-0.5, -0.5),
|
||||
(3.5, -0.5),
|
||||
(3.5, 2.5),
|
||||
(-0.5, 2.5)
|
||||
])
|
||||
]
|
||||
|
||||
l_b = 0.55
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
eq_(panel.wind_zone, wind_zone)
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 0)
|
||||
assert_has_wind_zone(panel_1_0, 1)
|
||||
assert_has_wind_zone(panel_2_0, 1)
|
||||
assert_has_wind_zone(panel_3_0, 0)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 1)
|
||||
assert_has_wind_zone(panel_1_1, 2)
|
||||
assert_has_wind_zone(panel_2_1, 2)
|
||||
assert_has_wind_zone(panel_3_1, 1)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 0)
|
||||
assert_has_wind_zone(panel_1_2, 1)
|
||||
assert_has_wind_zone(panel_2_2, 1)
|
||||
|
||||
def test_detect_dual_tilt_wind_zones_simple_rectangle_high_lb(self):
|
||||
system_type = SystemType.dualTilt
|
||||
|
||||
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
|
||||
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
|
||||
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
|
||||
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
|
||||
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
|
||||
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
|
||||
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
|
||||
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
|
||||
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
|
||||
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
|
||||
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
|
||||
|
||||
panels = [
|
||||
panel_0_2, panel_1_2, panel_2_2,
|
||||
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
|
||||
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
|
||||
]
|
||||
|
||||
sorted_panels = sorted(panels, key=lambda x: x.id)
|
||||
|
||||
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
|
||||
|
||||
buildings = [
|
||||
Polygon(points=[
|
||||
(-0.5, -0.5),
|
||||
(3.5, -0.5),
|
||||
(3.5, 2.5),
|
||||
(-0.5, 2.5)
|
||||
])
|
||||
]
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
eq_(panel.wind_zone, wind_zone)
|
||||
|
||||
l_b = 1
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 0)
|
||||
assert_has_wind_zone(panel_1_0, 0)
|
||||
assert_has_wind_zone(panel_2_0, 0)
|
||||
assert_has_wind_zone(panel_3_0, 0)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 0)
|
||||
assert_has_wind_zone(panel_1_1, 1)
|
||||
assert_has_wind_zone(panel_2_1, 1)
|
||||
assert_has_wind_zone(panel_3_1, 0)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 0)
|
||||
assert_has_wind_zone(panel_1_2, 0)
|
||||
assert_has_wind_zone(panel_2_2, 0)
|
||||
|
||||
def test_detect_dual_tilt_wind_zones_simple_rectangle_low_lb(self):
|
||||
system_type = SystemType.dualTilt
|
||||
|
||||
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
|
||||
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
|
||||
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
|
||||
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
|
||||
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
|
||||
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
|
||||
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
|
||||
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
|
||||
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
|
||||
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
|
||||
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
|
||||
|
||||
panels = [
|
||||
panel_0_2, panel_1_2, panel_2_2,
|
||||
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
|
||||
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
|
||||
]
|
||||
|
||||
sorted_panels = sorted(panels, key=lambda x: x.id)
|
||||
|
||||
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
|
||||
|
||||
buildings = [
|
||||
Polygon(points=[
|
||||
(-0.5, -0.5),
|
||||
(3.5, -0.5),
|
||||
(3.5, 2.5),
|
||||
(-0.5, 2.5)
|
||||
])
|
||||
]
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
eq_(panel.wind_zone, wind_zone)
|
||||
l_b = 0.3
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 1)
|
||||
assert_has_wind_zone(panel_1_0, 2)
|
||||
assert_has_wind_zone(panel_2_0, 2)
|
||||
assert_has_wind_zone(panel_3_0, 1)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 2)
|
||||
assert_has_wind_zone(panel_1_1, 3)
|
||||
assert_has_wind_zone(panel_2_1, 3)
|
||||
assert_has_wind_zone(panel_3_1, 2)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 1)
|
||||
assert_has_wind_zone(panel_1_2, 2)
|
||||
assert_has_wind_zone(panel_2_2, 2)
|
||||
|
||||
# try again with a lower l_B
|
||||
l_b = 0.3
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
eq_(panel.wind_zone, wind_zone)
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 1)
|
||||
assert_has_wind_zone(panel_1_0, 2)
|
||||
assert_has_wind_zone(panel_2_0, 2)
|
||||
assert_has_wind_zone(panel_3_0, 1)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 2)
|
||||
assert_has_wind_zone(panel_1_1, 3)
|
||||
assert_has_wind_zone(panel_2_1, 3)
|
||||
assert_has_wind_zone(panel_3_1, 2)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 1)
|
||||
assert_has_wind_zone(panel_1_2, 2)
|
||||
assert_has_wind_zone(panel_2_2, 2)
|
||||
|
||||
def test_detect_dual_tilt_wind_zones_simple_rectangle_very_low_lb(self):
|
||||
system_type = SystemType.dualTilt
|
||||
|
||||
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
|
||||
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
|
||||
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
|
||||
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
|
||||
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
|
||||
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
|
||||
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
|
||||
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
|
||||
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
|
||||
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
|
||||
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
|
||||
|
||||
panels = [
|
||||
panel_0_2, panel_1_2, panel_2_2,
|
||||
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
|
||||
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
|
||||
]
|
||||
|
||||
sorted_panels = sorted(panels, key=lambda x: x.id)
|
||||
|
||||
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
|
||||
|
||||
buildings = [
|
||||
Polygon(points=[
|
||||
(-0.5, -0.5),
|
||||
(3.5, -0.5),
|
||||
(3.5, 2.5),
|
||||
(-0.5, 2.5)
|
||||
])
|
||||
]
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
eq_(panel.wind_zone, wind_zone)
|
||||
l_b = 0.2
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 2)
|
||||
assert_has_wind_zone(panel_1_0, 3)
|
||||
assert_has_wind_zone(panel_2_0, 3)
|
||||
assert_has_wind_zone(panel_3_0, 2)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 3)
|
||||
assert_has_wind_zone(panel_1_1, 4)
|
||||
assert_has_wind_zone(panel_2_1, 4)
|
||||
assert_has_wind_zone(panel_3_1, 3)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 2)
|
||||
assert_has_wind_zone(panel_1_2, 3)
|
||||
assert_has_wind_zone(panel_2_2, 3)
|
||||
|
||||
# try again with a lower l_B
|
||||
l_b = 0.3
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
eq_(panel.wind_zone, wind_zone)
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 1)
|
||||
assert_has_wind_zone(panel_1_0, 2)
|
||||
assert_has_wind_zone(panel_2_0, 2)
|
||||
assert_has_wind_zone(panel_3_0, 1)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 2)
|
||||
assert_has_wind_zone(panel_1_1, 3)
|
||||
assert_has_wind_zone(panel_2_1, 3)
|
||||
assert_has_wind_zone(panel_3_1, 2)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 1)
|
||||
assert_has_wind_zone(panel_1_2, 2)
|
||||
assert_has_wind_zone(panel_2_2, 2)
|
||||
|
||||
def test_detect_single_tilt_wind_zones_simple_rectangle_mid_lb(self):
|
||||
system_type = SystemType.singleTilt
|
||||
|
||||
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
|
||||
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
|
||||
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
|
||||
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
|
||||
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
|
||||
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
|
||||
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
|
||||
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
|
||||
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
|
||||
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
|
||||
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
|
||||
panel_3_2 = Panel(coordinate=Coordinate(3, 2, rotation=0), id='3_2')
|
||||
|
||||
panels = [
|
||||
panel_0_2, panel_1_2, panel_2_2, panel_3_2,
|
||||
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
|
||||
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
|
||||
]
|
||||
|
||||
sorted_panels = sorted(panels, key=lambda x: x.id)
|
||||
|
||||
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
|
||||
|
||||
buildings = [
|
||||
Polygon(points=[
|
||||
(-0.5, -0.5),
|
||||
(3.5, -0.5),
|
||||
(3.5, 2.5),
|
||||
(-0.5, 2.5)
|
||||
])
|
||||
]
|
||||
|
||||
l_b = 0.55
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
assert wind_zone == panel.wind_zone, "Expected panel to be in wind_zone %d, got %d" % (wind_zone, panel.wind_zone)
|
||||
eq_(panel.wind_zone, wind_zone)
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 8)
|
||||
assert_has_wind_zone(panel_1_0, 7)
|
||||
assert_has_wind_zone(panel_2_0, 7)
|
||||
assert_has_wind_zone(panel_3_0, 8)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 9)
|
||||
assert_has_wind_zone(panel_1_1, 2)
|
||||
assert_has_wind_zone(panel_2_1, 2)
|
||||
assert_has_wind_zone(panel_3_1, 9)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 0)
|
||||
assert_has_wind_zone(panel_1_2, 2)
|
||||
assert_has_wind_zone(panel_2_2, 2)
|
||||
assert_has_wind_zone(panel_3_2, 0)
|
||||
|
||||
def test_detect_single_tilt_wind_zones_simple_rectangle_low_lb(self):
|
||||
system_type = SystemType.singleTilt
|
||||
|
||||
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
|
||||
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
|
||||
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
|
||||
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
|
||||
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
|
||||
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
|
||||
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
|
||||
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
|
||||
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
|
||||
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
|
||||
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
|
||||
panel_3_2 = Panel(coordinate=Coordinate(3, 2, rotation=0), id='3_2')
|
||||
|
||||
panels = [
|
||||
panel_0_2, panel_1_2, panel_2_2, panel_3_2,
|
||||
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
|
||||
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
|
||||
]
|
||||
|
||||
sorted_panels = sorted(panels, key=lambda x: x.id)
|
||||
|
||||
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
|
||||
|
||||
buildings = [
|
||||
Polygon(points=[
|
||||
(-0.5, -0.5),
|
||||
(3.5, -0.5),
|
||||
(3.5, 2.5),
|
||||
(-0.5, 2.5)
|
||||
])
|
||||
]
|
||||
|
||||
l_b = 0.35
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
assert wind_zone == panel.wind_zone, "Expected panel to be in wind_zone %d, got %d" % (wind_zone, panel.wind_zone)
|
||||
eq_(panel.wind_zone, wind_zone)
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E, 5 is F, 6 is G, 7 is H, 8 is I, 9 is J, 10 is K
|
||||
# A, I, H, B, J, C, E, F, G, D, K (order of most uplift force
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 9)
|
||||
assert_has_wind_zone(panel_1_0, 4)
|
||||
assert_has_wind_zone(panel_2_0, 4)
|
||||
assert_has_wind_zone(panel_3_0, 9)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 2)
|
||||
assert_has_wind_zone(panel_1_1, 5)
|
||||
assert_has_wind_zone(panel_2_1, 5)
|
||||
assert_has_wind_zone(panel_3_1, 2)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 0)
|
||||
assert_has_wind_zone(panel_1_2, 3)
|
||||
assert_has_wind_zone(panel_2_2, 3)
|
||||
assert_has_wind_zone(panel_3_2, 0)
|
||||
|
||||
def test_detect_dual_tilt_wind_zones_10_gon_building(self):
|
||||
system_type = SystemType.dualTilt
|
||||
|
||||
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
|
||||
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
|
||||
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
|
||||
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
|
||||
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
|
||||
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
|
||||
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
|
||||
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
|
||||
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
|
||||
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
|
||||
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
|
||||
|
||||
panels = [
|
||||
panel_0_2, panel_1_2, panel_2_2,
|
||||
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
|
||||
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
|
||||
]
|
||||
|
||||
sorted_panels = sorted(panels, key=lambda x: x.id)
|
||||
|
||||
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
|
||||
|
||||
points = []
|
||||
radius = 3
|
||||
building_vertices = 10
|
||||
for step in range(building_vertices, 0, -1): # create a 10-gon
|
||||
angle = (2 * pi / building_vertices) * step
|
||||
x = radius * sin(angle)
|
||||
y = radius * cos(angle)
|
||||
points.append((x, y))
|
||||
|
||||
buildings = [Polygon(points=points)]
|
||||
|
||||
l_b = 2
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
eq_(panel.wind_zone, wind_zone)
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 4)
|
||||
assert_has_wind_zone(panel_1_0, 4)
|
||||
assert_has_wind_zone(panel_2_0, 4)
|
||||
assert_has_wind_zone(panel_3_0, 4)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 4)
|
||||
assert_has_wind_zone(panel_1_1, 4)
|
||||
assert_has_wind_zone(panel_2_1, 4)
|
||||
assert_has_wind_zone(panel_3_1, 4)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 4)
|
||||
assert_has_wind_zone(panel_1_2, 4)
|
||||
assert_has_wind_zone(panel_2_2, 4)
|
||||
|
||||
def test_detect_dual_tilt_wind_zones_hexagon_building(self):
|
||||
system_type = SystemType.dualTilt
|
||||
|
||||
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
|
||||
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
|
||||
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
|
||||
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
|
||||
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
|
||||
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
|
||||
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
|
||||
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
|
||||
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
|
||||
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
|
||||
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
|
||||
|
||||
panels = [
|
||||
panel_0_2, panel_1_2, panel_2_2,
|
||||
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
|
||||
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
|
||||
]
|
||||
|
||||
sorted_panels = sorted(panels, key=lambda x: x.id)
|
||||
|
||||
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
|
||||
|
||||
points = []
|
||||
radius = 4
|
||||
building_vertices = 6
|
||||
for step in range(building_vertices, 0, -1): # create a 10-gon
|
||||
angle = (2 * pi / building_vertices) * step
|
||||
x = radius * sin(angle)
|
||||
y = radius * cos(angle)
|
||||
points.append((x + 1, y + 1))
|
||||
|
||||
buildings = [Polygon(points=points)]
|
||||
|
||||
l_b = 1
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
assert panel.wind_zone == wind_zone, "expected panel to be in wind zone %d, got %d" % (wind_zone, panel.wind_zone)
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 1)
|
||||
assert_has_wind_zone(panel_1_0, 2)
|
||||
assert_has_wind_zone(panel_2_0, 1)
|
||||
assert_has_wind_zone(panel_3_0, 1)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 2)
|
||||
assert_has_wind_zone(panel_1_1, 2)
|
||||
assert_has_wind_zone(panel_2_1, 2)
|
||||
assert_has_wind_zone(panel_3_1, 1)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 1)
|
||||
assert_has_wind_zone(panel_1_2, 2)
|
||||
assert_has_wind_zone(panel_2_2, 1)
|
||||
|
||||
def test_detect_dual_tilt_wind_zones_triangle_building(self):
|
||||
system_type = SystemType.dualTilt
|
||||
|
||||
panel_0_0 = Panel(coordinate=Coordinate(0, 0, rotation=0), id='0_0')
|
||||
panel_1_0 = Panel(coordinate=Coordinate(1, 0, rotation=0), id='1_0')
|
||||
panel_2_0 = Panel(coordinate=Coordinate(2, 0, rotation=0), id='2_0')
|
||||
panel_3_0 = Panel(coordinate=Coordinate(3, 0, rotation=0), id='3_0')
|
||||
panel_0_1 = Panel(coordinate=Coordinate(0, 1, rotation=0), id='0_1')
|
||||
panel_1_1 = Panel(coordinate=Coordinate(1, 1, rotation=0), id='1_1')
|
||||
panel_2_1 = Panel(coordinate=Coordinate(2, 1, rotation=0), id='2_1')
|
||||
panel_3_1 = Panel(coordinate=Coordinate(3, 1, rotation=0), id='3_1')
|
||||
panel_0_2 = Panel(coordinate=Coordinate(0, 2, rotation=0), id='0_2')
|
||||
panel_1_2 = Panel(coordinate=Coordinate(1, 2, rotation=0), id='1_2')
|
||||
panel_2_2 = Panel(coordinate=Coordinate(2, 2, rotation=0), id='2_2')
|
||||
|
||||
panels = [
|
||||
panel_0_2, panel_1_2, panel_2_2,
|
||||
panel_0_1, panel_1_1, panel_2_1, panel_3_1,
|
||||
panel_0_0, panel_1_0, panel_2_0, panel_3_0,
|
||||
]
|
||||
|
||||
sorted_panels = sorted(panels, key=lambda x: x.id)
|
||||
|
||||
modules = [Polygon(points=[(p.coordinate.x, p.coordinate.y)]) for p in sorted_panels]
|
||||
|
||||
points = []
|
||||
radius = 4
|
||||
building_vertices = 3
|
||||
for step in range(building_vertices, 0, -1): # create a 10-gon
|
||||
angle = (2 * pi / building_vertices) * step
|
||||
x = radius * sin(angle)
|
||||
y = radius * cos(angle)
|
||||
points.append((x + 1, y + 1))
|
||||
|
||||
buildings = [Polygon(points=points)]
|
||||
|
||||
l_b = 1
|
||||
self.subject.detect_wind_zones(panels, buildings, modules, l_b, system_type)
|
||||
|
||||
def assert_has_wind_zone(panel, wind_zone):
|
||||
assert panel.wind_zone == wind_zone, "expected panel to be in wind zone %d, got %d" % (wind_zone, panel.wind_zone)
|
||||
assert panel.fuzzy_wind_zone, "expected panel to be in a fuzzy wind zone"
|
||||
|
||||
# 0 is A, 1 is B, 2 is C, 3 is D, 4 is E
|
||||
|
||||
assert_has_wind_zone(panel_0_0, 1)
|
||||
assert_has_wind_zone(panel_1_0, 1)
|
||||
assert_has_wind_zone(panel_2_0, 1)
|
||||
assert_has_wind_zone(panel_3_0, 0)
|
||||
|
||||
assert_has_wind_zone(panel_0_1, 1)
|
||||
assert_has_wind_zone(panel_1_1, 2)
|
||||
assert_has_wind_zone(panel_2_1, 1)
|
||||
assert_has_wind_zone(panel_3_1, 1)
|
||||
|
||||
assert_has_wind_zone(panel_0_2, 1)
|
||||
assert_has_wind_zone(panel_1_2, 1)
|
||||
assert_has_wind_zone(panel_2_2, 1)
|
||||
|
||||
def test_compute_corner_directions(self):
|
||||
data = [
|
||||
{
|
||||
'building_points': [(0, 0), (10, 0), (10, 10), (0, 10)],
|
||||
'expected_corner_dirs': [(False, False), (False, True), (True, True), (True, False)]
|
||||
},
|
||||
{
|
||||
'building_points': [(0, 0), (10, 0), (2, 10)],
|
||||
'expected_corner_dirs': [(False, False), (False, True), (True, False)]
|
||||
},
|
||||
{
|
||||
'building_points': [(0, 0), (10, 0), (7, 10)],
|
||||
'expected_corner_dirs': [(False, False), (False, True), (True, True)]
|
||||
},
|
||||
{
|
||||
'building_points': [(0, 0), (10, 0), (7, 2)],
|
||||
'expected_corner_dirs': [(False, False), (False, True), (True, False)]
|
||||
},
|
||||
{
|
||||
'building_points': [(0, 0), (3, -10), (10, 0)],
|
||||
'expected_corner_dirs': [(True, False), (False, False), (True, True)]
|
||||
},
|
||||
{
|
||||
'building_points': [(-1, -1), (1, 4), (0, 10)],
|
||||
'expected_corner_dirs': [(False, False), (False, True), (True, False)]
|
||||
},
|
||||
{
|
||||
'building_points': [(1, -1), (0, 10), (-1, 4)],
|
||||
'expected_corner_dirs': [(False, True), (True, True), (False, False)]
|
||||
},
|
||||
{
|
||||
'building_points': [(0, 1), (4, 0), (8, 2)],
|
||||
'expected_corner_dirs': [(True, False), (False, True), (True, True)]
|
||||
},
|
||||
{
|
||||
'building_points': [(0, 2), (4, 0), (8, 1)],
|
||||
'expected_corner_dirs': [(True, False), (False, False), (True, True)]
|
||||
}
|
||||
]
|
||||
|
||||
for item in data:
|
||||
building = item['building_points']
|
||||
expected = item['expected_corner_dirs']
|
||||
|
||||
corners = []
|
||||
|
||||
for i in range(len(building)):
|
||||
corners.append((building[i - 1], building[i], building[(i + 1) % len(building)]))
|
||||
|
||||
for expected, (prev, vertex, next) in zip(expected, corners):
|
||||
print('given:', self.subject.compute_corner_directions(vertex, prev, next, 0))
|
||||
assert self.subject.compute_corner_directions(vertex, prev, next, 0) == expected
|
||||
93
test/helpers/image_presenter_test.py
Normal file
93
test/helpers/image_presenter_test.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import unittest
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
import mockredis
|
||||
from helix.calculators.calculator import Calculator
|
||||
from helix.constants.anchor_type import AnchorType
|
||||
from helix.constants.exposure_category import ExposureCategory
|
||||
from helix.constants.module_type import ModuleType
|
||||
from helix.constants.system_type import SystemType
|
||||
from helix.models.coordinate import Coordinate
|
||||
from helix.models.panel import Panel
|
||||
from helix.models.sql.sites import Site
|
||||
from helix.models.subarray import Subarray
|
||||
from helix.presenters.image_presenter import ImagePresenter
|
||||
from helix.store import Store
|
||||
from helix.user_values import UserValues
|
||||
from test.fixtures.sample_image_presented_panel_data import panels_pseries_single_tilt, subarrays_pseries_single_tilt
|
||||
from test.test_helpers import assert_image_equal
|
||||
|
||||
|
||||
class ImagePresenterTest(unittest.TestCase):
|
||||
def test_generate_image_taller_than_is_wide(self):
|
||||
# This is input_dual_tilt_128_crafted.tsv
|
||||
# With inputs as:
|
||||
# System Type: Dual-Tilt
|
||||
# Module Type: 128 Cell
|
||||
# Building Height: 100.0
|
||||
# Building Width: 50.0
|
||||
# Building Length: 100.0
|
||||
# Parapet Height: 0.0
|
||||
# Wind Speed: 110
|
||||
# Exposure Category: C
|
||||
# Ballast Block Weight: 14.0
|
||||
# Max Allowable System Pressure: 10.0
|
||||
# Anchor Type: OMG PowerGrip Plus
|
||||
# S_DS: 1.0
|
||||
panels = [
|
||||
Panel(wind_zone=3, subarray=1, coordinate=Coordinate(0, 0), ballast=20, wind_anchors=0, seismic_anchors=0),
|
||||
Panel(wind_zone=3, subarray=1, coordinate=Coordinate(0, 1), ballast=0, wind_anchors=0, seismic_anchors=1),
|
||||
|
||||
Panel(wind_zone=2, subarray=2, coordinate=Coordinate(0, 0), ballast=8, wind_anchors=1, seismic_anchors=0),
|
||||
Panel(wind_zone=2, subarray=2, coordinate=Coordinate(1, 0), ballast=0, wind_anchors=1, seismic_anchors=1),
|
||||
Panel(wind_zone=2, subarray=2, coordinate=Coordinate(0, 1), ballast=0, wind_anchors=1, seismic_anchors=1),
|
||||
Panel(wind_zone=2, subarray=2, coordinate=Coordinate(1, 1), ballast=0, wind_anchors=1, seismic_anchors=1)
|
||||
]
|
||||
|
||||
subarrays = [
|
||||
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=2),
|
||||
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=2, size=4)
|
||||
]
|
||||
|
||||
expected_image = Image.open("test/fixtures/images/expected_dual_tilt_pseries_image.png")
|
||||
received_bytes = ImagePresenter(SystemType.dualTilt, ModuleType.Cell128).generate_image(panels, subarrays)
|
||||
|
||||
received_image = Image.open(BytesIO(received_bytes))
|
||||
|
||||
assert_image_equal(received_image, expected_image, error=0.001)
|
||||
|
||||
def test_generate_image_wider_than_is_tall(self):
|
||||
# This is input_single_tilt_pseries_coordinates.tsv
|
||||
# With inputs as:
|
||||
# System Type: Single-Tilt
|
||||
# Module Type: P-Series
|
||||
# Building Height: 100.0
|
||||
# Building Width: 100.0
|
||||
# Building Length: 100.0
|
||||
# Parapet Height: 1.0
|
||||
# Wind Speed: 100
|
||||
# Exposure Category: C
|
||||
# Ballast Block Weight: 14.0
|
||||
# Max Allowable System Pressure: 12.0
|
||||
# Anchor Type: OMG PowerGrip Plus
|
||||
# S_DS: 1.0
|
||||
panels = panels_pseries_single_tilt
|
||||
subarrays = subarrays_pseries_single_tilt
|
||||
|
||||
expected_image = Image.open("test/fixtures/images/expected_single_tilt_pseries_image.png")
|
||||
received_bytes = ImagePresenter(SystemType.singleTilt, ModuleType.PSeries).generate_image(panels, subarrays)
|
||||
|
||||
received_image = Image.open(BytesIO(received_bytes))
|
||||
|
||||
assert_image_equal(received_image, expected_image, error=0.5)
|
||||
|
||||
def test_return_image_stating_system_too_large_if_more_than_3000_panels_submitted(self):
|
||||
panels = [Panel() for _ in range(3000)]
|
||||
subarrays = []
|
||||
|
||||
expected_image = Image.open("test/fixtures/images/expected_too_many_panels.png")
|
||||
received_bytes = ImagePresenter(SystemType.singleTilt, ModuleType.PSeries).generate_image(panels, subarrays)
|
||||
|
||||
received_image = Image.open(BytesIO(received_bytes))
|
||||
|
||||
assert_image_equal(received_image, expected_image, error=5e-2)
|
||||
77
test/helpers/nodequadtree_test.py
Normal file
77
test/helpers/nodequadtree_test.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import unittest
|
||||
from nose.tools import eq_
|
||||
from helix.helpers.nodequadtree import Bounds, NodeQuadTree
|
||||
from helix.models.coordinate import Coordinate
|
||||
|
||||
class DummyNode:
|
||||
def __init__(self, x, y):
|
||||
self.coordinate = Coordinate(x, y)
|
||||
|
||||
class NodeQuadTreeTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.quadTree = NodeQuadTree(1, Bounds(0, 100, 0, 100), 0.5)
|
||||
|
||||
def test_lower_leaves(self):
|
||||
nodes = [
|
||||
DummyNode(1, 1),
|
||||
DummyNode(4, 1),
|
||||
DummyNode(6, 1),
|
||||
DummyNode(9, 1),
|
||||
DummyNode(1, 9),
|
||||
DummyNode(4, 9),
|
||||
DummyNode(6, 9),
|
||||
DummyNode(9, 9)
|
||||
]
|
||||
|
||||
for i in range(100):
|
||||
for n in nodes:
|
||||
self.quadTree.insert(n)
|
||||
|
||||
output = []
|
||||
self.quadTree.report(output)
|
||||
|
||||
expected = [0, 0, 0, 0, 200, 200, 200, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
eq_(output, expected)
|
||||
|
||||
def test_top_level_degenerate(self):
|
||||
nodes = []
|
||||
for i in range(0, 100):
|
||||
nodes.append(DummyNode(50, i))
|
||||
nodes.append(DummyNode(i, 50))
|
||||
|
||||
for n in nodes:
|
||||
self.quadTree.insert(n)
|
||||
|
||||
output = []
|
||||
self.quadTree.report(output)
|
||||
|
||||
expected = [200, 0, 0, 0, 0]
|
||||
eq_(output, expected)
|
||||
|
||||
def test_every_point(self):
|
||||
nodes = []
|
||||
for x in range(0, 100):
|
||||
for y in range(0, 100):
|
||||
nodes.append(DummyNode(x, y))
|
||||
|
||||
for n in nodes:
|
||||
self.quadTree.insert(n)
|
||||
|
||||
output = []
|
||||
self.quadTree.report(output)
|
||||
|
||||
expected = [199, 0, 49, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 49, 23,
|
||||
30, 25, 36, 30, 23, 30, 25, 36, 30, 23, 30, 25, 36, 30, 23, 30, 25, 36, 30, 49, 23, 30, 36, 25, 30,
|
||||
23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 49, 23, 36, 30, 30, 25, 23, 36, 30, 30,
|
||||
25, 23, 36, 30, 30, 25, 23, 36, 30, 30, 25, 0, 49, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25,
|
||||
30, 30, 36, 23, 25, 30, 30, 36, 48, 23, 30, 25, 36, 30, 22, 30, 20, 36, 24, 23, 30, 25, 36, 30, 22,
|
||||
30, 20, 36, 24, 49, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30,
|
||||
48, 23, 36, 30, 30, 25, 22, 36, 24, 30, 20, 23, 36, 30, 30, 25, 22, 36, 24, 30, 20, 0, 49, 23, 25,
|
||||
30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 49, 23, 30, 25, 36, 30, 23,
|
||||
30, 25, 36, 30, 23, 30, 25, 36, 30, 23, 30, 25, 36, 30, 48, 23, 30, 36, 25, 30, 23, 30, 36, 25, 30,
|
||||
22, 30, 36, 20, 24, 22, 30, 36, 20, 24, 48, 23, 36, 30, 30, 25, 23, 36, 30, 30, 25, 22, 36, 30, 24,
|
||||
20, 22, 36, 30, 24, 20, 0, 49, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25, 30, 30, 36, 23, 25,
|
||||
30, 30, 36, 48, 23, 30, 25, 36, 30, 22, 30, 20, 36, 24, 23, 30, 25, 36, 30, 22, 30, 20, 36, 24, 48,
|
||||
23, 30, 36, 25, 30, 23, 30, 36, 25, 30, 22, 30, 36, 20, 24, 22, 30, 36, 20, 24, 47, 23, 36, 30, 30,
|
||||
25, 22, 36, 24, 30, 20, 22, 36, 30, 24, 20, 21, 36, 24, 24, 16]
|
||||
eq_(output, expected)
|
||||
244
test/helpers/panel_presenter_test.py
Normal file
244
test/helpers/panel_presenter_test.py
Normal file
@@ -0,0 +1,244 @@
|
||||
import unittest
|
||||
|
||||
from numpy.testing import assert_array_equal, assert_equal
|
||||
from helix.constants.module_type import ModuleType
|
||||
|
||||
from helix.models.coordinate import Coordinate
|
||||
from helix.models.panel import Panel
|
||||
from helix.models.subarray import Subarray
|
||||
from helix.presenters.panel_presenter import ProjectPresenter
|
||||
from helix.constants.system_type import SystemType
|
||||
from helix.constants.panel_type import PanelType
|
||||
|
||||
|
||||
class PanelPresenterTest(unittest.TestCase):
|
||||
|
||||
|
||||
def test_get_table_data_single_tilt_96cell(self):
|
||||
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
|
||||
panels = [
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.17, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.17, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 1), pressure=1.17, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=3),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 1), pressure=1.17, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=4),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=5),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(3, 0), pressure=1.17, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=6),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 0), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=7),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 0), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=8),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0), pressure=1.17, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=9),
|
||||
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 1), pressure=2.56, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=10),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1), pressure=2.56, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=11),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Middle, coordinate=Coordinate(1, 1), pressure=2.56, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=12),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(0, 1), pressure=2.56, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=13),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 0), pressure=2.56, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=14),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(2, 0), pressure=2.56, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=15),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0), pressure=2.56, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=16)
|
||||
]
|
||||
|
||||
subarrays = [
|
||||
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=9),
|
||||
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=9, size=7)
|
||||
]
|
||||
|
||||
expected = [
|
||||
{'x': 0, 'y': 1, 'width': 1, 'height': 1, 'data': {'panel_id': 1, 'panel_type': 4, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 3, 'y': 2, 'width': 1, 'height': 1, 'data': {'panel_id': 2, 'panel_type': 2, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 2, 'y': 2, 'width': 1, 'height': 1, 'data': {'panel_id': 3, 'panel_type': 2, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 0, 'link_trays': 0, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 1, 'y': 2, 'width': 1, 'height': 1, 'data': {'panel_id': 4, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 4, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 0, 'y': 2, 'width': 1, 'height': 1, 'data': {'panel_id': 5, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 3, 'y': 3, 'width': 1, 'height': 1, 'data': {'panel_id': 6, 'panel_type': 3, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 0, 'link_trays': 1, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 2, 'y': 3, 'width': 1, 'height': 1, 'data': {'panel_id': 7, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 1, 'y': 3, 'width': 1, 'height': 1, 'data': {'panel_id': 8, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 0, 'y': 3, 'width': 1, 'height': 1, 'data': {'panel_id': 9, 'panel_type': 1, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 3, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
|
||||
{'x': 3, 'y': 0, 'width': 1, 'height': 1, 'data': {'panel_id': 10, 'panel_type': 1, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 1, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 2, 'y': 0, 'width': 1, 'height': 1, 'data': {'panel_id': 11, 'panel_type': 3, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 1, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 1, 'y': 0, 'width': 1, 'height': 1, 'data': {'panel_id': 12, 'panel_type': 4, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 0, 'link_trays': 0, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 0, 'y': 0, 'width': 1, 'height': 1, 'data': {'panel_id': 13, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 4, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 3, 'y': 1, 'width': 1, 'height': 1, 'data': {'panel_id': 14, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 2, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 2, 'y': 1, 'width': 1, 'height': 1, 'data': {'panel_id': 15, 'panel_type': 1, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 0, 'link_trays': 1, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 1, 'y': 1, 'width': 1, 'height': 1, 'data': {'panel_id': 16, 'panel_type': 2, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 3, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
]
|
||||
|
||||
received = self.subject.get_panel_data(panels, subarrays)
|
||||
assert_array_equal(received, expected)
|
||||
|
||||
def test_get_buildings_data(self):
|
||||
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
|
||||
buildings = [ [ Coordinate(-60,-60), Coordinate(60,-60), Coordinate(60,60), Coordinate(-60,60) ] ] # big square
|
||||
expected_buildings = [[ {'x': -60, '_Coordinate__rounded_x': -60, 'y': 60, '_Coordinate__rounded_y': -60, 'rotation': 0.0},
|
||||
{'x': 60, '_Coordinate__rounded_x': 60, 'y': 60, '_Coordinate__rounded_y': -60, 'rotation': 0.0},
|
||||
{'x': 60, '_Coordinate__rounded_x': 60, 'y': -60, '_Coordinate__rounded_y': 60, 'rotation': 0.0},
|
||||
{'x': -60, '_Coordinate__rounded_x': -60, 'y': -60, '_Coordinate__rounded_y': 60, 'rotation': 0.0}]]
|
||||
actual_buildings = self.subject.get_buildings(buildings)
|
||||
assert_array_equal(actual_buildings,expected_buildings)
|
||||
|
||||
def test_get_max_y(self):
|
||||
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
|
||||
panels = [
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.17, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.17, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
|
||||
]
|
||||
buildings = [ [ Coordinate(-60,-60), Coordinate(60,-60), Coordinate(60,60), Coordinate(-60,60) ] ] # big square
|
||||
expected_max_y = 60
|
||||
actual_max_y = self.subject.get_max_y(buildings,panels)
|
||||
assert_equal(actual_max_y, expected_max_y)
|
||||
|
||||
expected_max_y = 2
|
||||
actual_max_y = self.subject.get_max_y([],panels)
|
||||
assert_equal(actual_max_y, expected_max_y)
|
||||
|
||||
|
||||
|
||||
|
||||
def test_get_table_data_single_tilt_128cell(self):
|
||||
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell128)
|
||||
panels = [
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.17, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.17, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 1), pressure=1.17, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=3),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 1), pressure=1.17, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=4),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=5),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(3, 0), pressure=1.17, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=6),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 0), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=7),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 0), pressure=1.17, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=8),
|
||||
Panel(wind_zone=0, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0), pressure=1.17, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=9),
|
||||
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 1), pressure=2.56, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=10),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1), pressure=2.56, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=11),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Middle, coordinate=Coordinate(1, 1), pressure=2.56, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=12),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(0, 1), pressure=2.56, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=13),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 0), pressure=2.56, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=14),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(2, 0), pressure=2.56, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=15),
|
||||
Panel(wind_zone=3, subarray=2, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0), pressure=2.56, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=16)
|
||||
]
|
||||
|
||||
subarrays= [
|
||||
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=9),
|
||||
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=9, size=7)
|
||||
]
|
||||
|
||||
expected = [
|
||||
{'x': 0.0, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 1, 'panel_type': 4, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 4.5, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 2, 'panel_type': 2, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 3.0, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 3, 'panel_type': 2, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 0, 'link_trays': 0, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 1.5, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 4, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 4, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 0.0, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 5, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 4.5, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 6, 'panel_type': 3, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 0, 'link_trays': 1, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 3.0, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 7, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 1.5, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 8, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
{'x': 0.0, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 9, 'panel_type': 1, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'A', 'cross_trays': 3, 'link_trays': 2, 'psf': 1.17, 'subarray': 1}},
|
||||
|
||||
{'x': 4.5, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 10, 'panel_type': 1, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 1, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 3.0, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 11, 'panel_type': 3, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 1, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 1.5, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 12, 'panel_type': 4, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 0, 'link_trays': 0, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 0.0, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 13, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 4, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 4.5, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 14, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 2, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 3.0, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 15, 'panel_type': 1, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 0, 'link_trays': 1, 'psf': 2.56, 'subarray': 2}},
|
||||
{'x': 1.5, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 16, 'panel_type': 2, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'D', 'cross_trays': 3, 'link_trays': 2, 'psf': 2.56, 'subarray': 2}},
|
||||
]
|
||||
|
||||
received = self.subject.get_panel_data(panels, subarrays)
|
||||
assert_array_equal(received, expected)
|
||||
|
||||
def test_get_table_data_dual_tilt_96cell(self):
|
||||
self.subject = ProjectPresenter(SystemType.dualTilt, ModuleType.Cell96)
|
||||
|
||||
panels =[
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.23, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.23, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 1), pressure=1.23, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=3),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 1), pressure=1.23, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=4),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=5),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(3, 0), pressure=1.23, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=6),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 0), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=7),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 0), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=8),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0), pressure=1.23, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=9),
|
||||
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 1), pressure=3.14, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=10),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1), pressure=3.14, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=11),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Middle, coordinate=Coordinate(1, 1), pressure=3.14, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=12),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(0, 1), pressure=3.14, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=13),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 0), pressure=3.14, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=14),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(2, 0), pressure=3.14, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=15),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0), pressure=3.14, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=16)
|
||||
]
|
||||
|
||||
subarrays = [
|
||||
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=9),
|
||||
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=9, size=7)
|
||||
]
|
||||
|
||||
expected = [
|
||||
{'x': 0.0, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 1, 'panel_type': 4, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 4.5, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 2, 'panel_type': 2, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 3.0, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 3, 'panel_type': 2, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 0, 'link_trays': 0, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 1.5, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 4, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 4, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 0.0, 'y': 2, 'width': 1.5, 'height': 1, 'data': {'panel_id': 5, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 4.5, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 6, 'panel_type': 3, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 0, 'link_trays': 1, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 3.0, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 7, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 1.5, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 8, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 0.0, 'y': 3, 'width': 1.5, 'height': 1, 'data': {'panel_id': 9, 'panel_type': 1, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 3, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
|
||||
{'x': 4.5, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 10, 'panel_type': 1, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 1, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 3.0, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 11, 'panel_type': 3, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 1, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 1.5, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 12, 'panel_type': 4, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 0, 'link_trays': 0, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 0.0, 'y': 0, 'width': 1.5, 'height': 1, 'data': {'panel_id': 13, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 4, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 4.5, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 14, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 2, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 3.0, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 15, 'panel_type': 1, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 0, 'link_trays': 1, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 1.5, 'y': 1, 'width': 1.5, 'height': 1, 'data': {'panel_id': 16, 'panel_type': 2, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 3, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
]
|
||||
|
||||
received = self.subject.get_panel_data(panels, subarrays)
|
||||
assert_array_equal(received, expected)
|
||||
|
||||
def test_get_table_data_dual_tilt_128cell(self):
|
||||
self.subject = ProjectPresenter(SystemType.dualTilt, ModuleType.Cell128)
|
||||
panels =[
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Middle, coordinate=Coordinate(0, 2), pressure=1.23, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=1),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(3, 1), pressure=1.23, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=2),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.NorthSouth, coordinate=Coordinate(2, 1), pressure=1.23, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=3),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 1), pressure=1.23, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=4),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(0, 1), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=5),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(3, 0), pressure=1.23, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=6),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 0), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=7),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(1, 0), pressure=1.23, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=8),
|
||||
Panel(wind_zone=4, subarray=1, panel_type=PanelType.Corner, coordinate=Coordinate(0, 0), pressure=1.23, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=9),
|
||||
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 1), pressure=3.14, ballast=20, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=10),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.EastWest, coordinate=Coordinate(2, 1), pressure=3.14, ballast=17, presented_link_tray=2, cross_tray=1, wind_anchors=0, seismic_anchors=1, id=11),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Middle, coordinate=Coordinate(1, 1), pressure=3.14, ballast=0, presented_link_tray=0, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=12),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(0, 1), pressure=3.14, ballast=47, presented_link_tray=2, cross_tray=4, wind_anchors=0, seismic_anchors=1, id=13),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(3, 0), pressure=3.14, ballast=22, presented_link_tray=2, cross_tray=2, wind_anchors=0, seismic_anchors=1, id=14),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.Corner, coordinate=Coordinate(2, 0), pressure=3.14, ballast=8, presented_link_tray=1, cross_tray=0, wind_anchors=0, seismic_anchors=1, id=15),
|
||||
Panel(wind_zone=1, subarray=2, panel_type=PanelType.NorthSouth, coordinate=Coordinate(1, 0), pressure=3.14, ballast=35, presented_link_tray=2, cross_tray=3, wind_anchors=0, seismic_anchors=1, id=16)
|
||||
]
|
||||
|
||||
subarrays = [
|
||||
Subarray(subarray_number=1, origin=Coordinate(0, 0), start_row=0, size=9),
|
||||
Subarray(subarray_number=2, origin=Coordinate(0, 2), start_row=9, size=7)
|
||||
]
|
||||
|
||||
expected = [
|
||||
{'x': 0.0, 'y': 1.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 1, 'panel_type': 4, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 4.5, 'y': 3.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 2, 'panel_type': 2, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 1, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 3.0, 'y': 3.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 3, 'panel_type': 2, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 0, 'link_trays': 0, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 1.5, 'y': 3.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 4, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 4, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 0.0, 'y': 3.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 5, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 4.5, 'y': 4.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 6, 'panel_type': 3, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 0, 'link_trays': 1, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 3.0, 'y': 4.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 7, 'panel_type': 3, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 1.5, 'y': 4.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 8, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 2, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
{'x': 0.0, 'y': 4.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 9, 'panel_type': 1, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'E', 'cross_trays': 3, 'link_trays': 2, 'psf': 1.23, 'subarray': 1}},
|
||||
|
||||
{'x': 4.5, 'y': 0.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 10, 'panel_type': 1, 'ballast': 20, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 1, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 3.0, 'y': 0.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 11, 'panel_type': 3, 'ballast': 17, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 1, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 1.5, 'y': 0.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 12, 'panel_type': 4, 'ballast': 0, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 0, 'link_trays': 0, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 0.0, 'y': 0.0, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 13, 'panel_type': 1, 'ballast': 47, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 4, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 4.5, 'y': 1.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 14, 'panel_type': 1, 'ballast': 22, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 2, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 3.0, 'y': 1.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 15, 'panel_type': 1, 'ballast': 8, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 0, 'link_trays': 1, 'psf': 3.14, 'subarray': 2}},
|
||||
{'x': 1.5, 'y': 1.5, 'width': 1.5, 'height': 1.5, 'data': {'panel_id': 16, 'panel_type': 2, 'ballast': 35, 'wind_anchors': 0, 'seismic_anchors': 1, 'wind_zones': 'B', 'cross_trays': 3, 'link_trays': 2, 'psf': 3.14, 'subarray': 2}},
|
||||
]
|
||||
|
||||
received = self.subject.get_panel_data(panels, subarrays)
|
||||
assert_array_equal(received, expected)
|
||||
55
test/helpers/subarray_helper_test.py
Normal file
55
test/helpers/subarray_helper_test.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import unittest
|
||||
from nose.tools import eq_
|
||||
from helix.calculators.subarray_helper import get_subarray_sizes_and_rows, extract_subarray
|
||||
from helix.models.panel import Panel
|
||||
from helix.models.subarray import Subarray
|
||||
|
||||
|
||||
class SubarrayHelperTest(unittest.TestCase):
|
||||
def test_get_subarray_sizes_and_rows(self):
|
||||
panels = [
|
||||
Panel(ballast=5, subarray=2),
|
||||
Panel(ballast=6, subarray=2),
|
||||
Panel(ballast=2, subarray=2),
|
||||
Panel(ballast=1, subarray=5),
|
||||
Panel(ballast=5, subarray=5),
|
||||
Panel(ballast=6, subarray=5),
|
||||
Panel(ballast=8, subarray=5),
|
||||
Panel(ballast=2, subarray=5),
|
||||
Panel(ballast=2, subarray=6),
|
||||
Panel(ballast=2, subarray=6)
|
||||
]
|
||||
|
||||
result = get_subarray_sizes_and_rows(panels)
|
||||
expected = [
|
||||
Subarray(subarray_number=2, start_row=0, size=3),
|
||||
Subarray(subarray_number=5, start_row=3, size=5),
|
||||
Subarray(subarray_number=6, start_row=8, size=2)
|
||||
]
|
||||
|
||||
eq_(expected, result)
|
||||
|
||||
def test_extract_subarray(self):
|
||||
panels = [
|
||||
Panel(ballast=5, subarray=2),
|
||||
Panel(ballast=6, subarray=2),
|
||||
Panel(ballast=2, subarray=2),
|
||||
Panel(ballast=1, subarray=5),
|
||||
Panel(ballast=5, subarray=5),
|
||||
Panel(ballast=6, subarray=5),
|
||||
Panel(ballast=8, subarray=5),
|
||||
Panel(ballast=2, subarray=5),
|
||||
Panel(ballast=2, subarray=6),
|
||||
Panel(ballast=2, subarray=6)
|
||||
]
|
||||
|
||||
result = extract_subarray(panels, 5)
|
||||
|
||||
expected = [
|
||||
Panel(ballast=1, subarray=5),
|
||||
Panel(ballast=5, subarray=5),
|
||||
Panel(ballast=6, subarray=5),
|
||||
Panel(ballast=8, subarray=5),
|
||||
Panel(ballast=2, subarray=5)
|
||||
]
|
||||
eq_(result, expected)
|
||||
Reference in New Issue
Block a user