Files
old-krovovi-kalkulator/test/helpers/doc_gen_params_builder_test.py
2017-11-21 17:11:29 +01:00

559 lines
18 KiB
Python

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),
('521794', 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_521794': 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)