import json import unittest import mockredis from nose.tools import eq_ from numpy.testing import assert_array_equal from helix.constants.module_type import ModuleType from helix.constants.exposure_category import ExposureCategory from helix.constants.inverter_type import InverterType from helix.constants.module_type_constants.dual_tilt_96_cell_constants import DualTilt96CellConstants from helix.constants.module_type_constants.single_tilt_96_cell_constants import SingleTilt96CellConstants from helix.constants.panel_type import PanelType from helix.constants.system_type import SystemType from helix.constants.anchor_type import AnchorType from helix.models.coordinate import Coordinate from helix.models.panel import Panel from helix.models.sql.inverters import Inverter from helix.models.sql.power_monitors import PowerMonitor 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.store import Store from helix.user_values import UserValues class UserValuesTest(unittest.TestCase): def setUp(self): self.site = Site( project_name='', building_height=0, building_width=0, building_length=0, parapet_height=0, wind_speed=0, exposure_category='C', exposure_transition_distance=0, ballast_block_weight=0, max_psf=0, system_type=SystemType.dualTilt.value, module_type=ModuleType.Cell96.value, anchor_type=AnchorType.OMG_PowerGrip_Plus.value, spectral_response=0, seismic_importance_factor=1, ) self.store = Store(mockredis.mock_redis_client(), "foo") self.subject = UserValues(self.store, self.site) csv_file = open('test/fixtures/input_dual_tilt.csv', 'r') csv_contents = csv_file.read() csv_file.close() self.site.cad_file = csv_contents def test_project_name(self): eq_(self.subject.project_name(), '') self.site.project_name = '\t\n@_name' eq_(self.subject.project_name(), '\t\n@_name') def test_project_name_no_spaces(self): eq_(self.subject.project_name_no_spaces(), '') self.site.project_name = 'Test Project Name' eq_(self.subject.project_name_no_spaces(), 'test_project_name') def test_module_type(self): eq_(self.subject.module_type(), ModuleType.Cell96) self.site.module_type = ModuleType.Cell128.value eq_(self.subject.module_type(), ModuleType.Cell128) def test_building_height(self): eq_(self.subject.building_height(), 0) self.site.building_height = 20 eq_(self.subject.building_height(), 20) def test_building_width(self): eq_(self.subject.building_width(), 0) self.site.building_width = 20 eq_(self.subject.building_width(), 20) def test_building_length(self): eq_(self.subject.building_length(), 0) self.site.building_length = 20 eq_(self.subject.building_length(), 20) def test_building_parapet_height(self): eq_(self.subject.building_parapet_height(), 0) self.site.parapet_height = 20 eq_(self.subject.building_parapet_height(), 20) def test_exposure_category(self): eq_(self.subject.exposure_category(), ExposureCategory.C) self.site.exposure_category = "D" eq_(self.subject.exposure_category(), ExposureCategory.D) def test_exposure_category_interpolation(self): self.site.exposure_category = "B to C" self.site.exposure_transition_distance = 2000 eq_(self.subject.exposure_category(), ExposureCategory.B_C) eq_(self.subject.exposure_category_transition_distance(), 2000) def test_wind_speed(self): eq_(self.subject.wind_speed(), 0.0) self.site.wind_speed = 20 eq_(self.subject.wind_speed(), 20.0) def test_ballast_block_weight(self): eq_(self.subject.ballast_block_weight(), 0.0) self.site.ballast_block_weight = 20 eq_(self.subject.ballast_block_weight(), 20.0) def test_max_allowable_system_pressure(self): eq_(self.subject.max_system_pressure(), 0) self.site.max_psf = 100.2 eq_(self.subject.max_system_pressure(), 100.2) def test_system_type(self): eq_(self.subject.system_type(), SystemType.dualTilt) self.site.system_type = '0' eq_(self.subject.system_type(), SystemType.singleTilt) def test_module_system_constants(self): assert type(self.subject.module_system_constants()) is DualTilt96CellConstants self.site.system_type = '0' assert type(self.subject.module_system_constants()) is SingleTilt96CellConstants def test_anchor_type(self): eq_(self.subject.anchor_type(), AnchorType.OMG_PowerGrip_Plus) self.site.anchor_type = AnchorType.OMG_PowerGrip.value eq_(self.subject.anchor_type(), AnchorType.OMG_PowerGrip) def test_spectral_response(self): eq_(self.subject.spectral_response(), 0) self.site.spectral_response = 2.5 eq_(self.subject.spectral_response(), 2.5) def test_importance_factor(self): eq_(self.subject.importance_factor(), 1) self.site.seismic_importance_factor = 1.5 eq_(self.subject.importance_factor(), 1.5) def test_csv_parsing(self): parsed_csv = self.subject.csv() expected_result = [ Panel(handle="'21EEE0", blockname="*U593", wind_zone=2, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(0, 0, 0), original_coordinate=Coordinate(0, 0, 0)), Panel(handle="'21EECC", blockname="*U824", wind_zone=2, panel_type=PanelType.NorthSouth, subarray=1, coordinate=Coordinate(0, 0, 0), original_coordinate=Coordinate(0, 0, 0)), Panel(handle="'21EEB8", blockname="*U824", wind_zone=4, panel_type=PanelType.EastWest, subarray=1, coordinate=Coordinate(0, 0, 0), original_coordinate=Coordinate(0, 0, 0)), Panel(handle="'21EEA4", blockname="*U593", wind_zone=0, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(0, 0, 0), original_coordinate=Coordinate(0, 0, 0)), Panel(handle="'21E940", blockname="*U171", wind_zone=1, panel_type=PanelType.Middle, subarray=1, coordinate=Coordinate(0, 0, 0), original_coordinate=Coordinate(0, 0, 0)), Panel(handle="'21E92C", blockname="*U824", wind_zone=3, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(0, 0, 0), original_coordinate=Coordinate(0, 0, 0)), Panel(handle="'21E918", blockname="*U593", wind_zone=1, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(0, 0, 0), original_coordinate=Coordinate(0, 0, 0)) ] assert_array_equal(parsed_csv, expected_result) def test_csv_parsing_with_coordinates(self): csv_file = open('test/fixtures/input_dual_tilt_coordinates.csv', 'r') csv_contents = csv_file.read() csv_file.close() self.site.cad_file = csv_contents expected_result = [ Panel(handle="'B247D", blockname="*U6006", wind_zone=0, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(30043.319, -61598.761, rotation=2.534306), original_coordinate=Coordinate(30043.319, -61598.761, rotation=2.534306)), Panel(handle="'B245F", blockname="*U6006", wind_zone=0, panel_type=PanelType.NorthSouth, subarray=1, coordinate=Coordinate(29955.165, -61602.663, rotation=2.534306), original_coordinate=Coordinate(29955.165, -61602.663, rotation=2.534306)), Panel(handle="'B2441", blockname="*U6006", wind_zone=0, panel_type=PanelType.NorthSouth, subarray=1, coordinate=Coordinate(29867.012, -61606.565, rotation=2.534306), original_coordinate=Coordinate(29867.012, -61606.565, rotation=2.534306)), Panel(handle="'B2423", blockname="*U6006", wind_zone=0, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(29778.858, -61610.467, rotation=2.534306), original_coordinate=Coordinate(29778.858, -61610.467, rotation=2.534306)), Panel(handle="'B2405", blockname="*U6006", wind_zone=0, panel_type=PanelType.EastWest, subarray=1, coordinate=Coordinate(30046.068, -61660.860, rotation=2.534306), original_coordinate=Coordinate(30046.068, -61660.860, rotation=2.534306)), Panel(handle="'B23E7", blockname="*U6006", wind_zone=0, panel_type=PanelType.Middle, subarray=1, coordinate=Coordinate(29957.914, -61664.762, rotation=2.534306), original_coordinate=Coordinate(29957.914, -61664.762, rotation=2.534306)), Panel(handle="'B23C9", blockname="*U6006", wind_zone=0, panel_type=PanelType.Middle, subarray=1, coordinate=Coordinate(29869.760, -61668.664, rotation=2.534306), original_coordinate=Coordinate(29869.760, -61668.664, rotation=2.534306)), Panel(handle="'B23AB", blockname="*U6006", wind_zone=0, panel_type=PanelType.EastWest, subarray=1, coordinate=Coordinate(29781.607, -61672.566, rotation=2.534306), original_coordinate=Coordinate(29781.607, -61672.566, rotation=2.534306)), Panel(handle="'B238D", blockname="*U6007", wind_zone=0, panel_type=PanelType.EastWest, subarray=1, coordinate=Coordinate(30048.816, -61722.960, rotation=2.534306), original_coordinate=Coordinate(30048.816, -61722.960, rotation=2.534306)), Panel(handle="'B236F", blockname="*U6007", wind_zone=0, panel_type=PanelType.Middle, subarray=1, coordinate=Coordinate(29960.663, -61726.861, rotation=2.534306), original_coordinate=Coordinate(29960.663, -61726.861, rotation=2.534306)), Panel(handle="'B2351", blockname="*U6007", wind_zone=0, panel_type=PanelType.Middle, subarray=1, coordinate=Coordinate(29872.509, -61730.763, rotation=2.534306), original_coordinate=Coordinate(29872.509, -61730.763, rotation=2.534306)), Panel(handle="'B2333", blockname="*U6007", wind_zone=0, panel_type=PanelType.EastWest, subarray=1, coordinate=Coordinate(29784.355, -61734.665, rotation=2.534306), original_coordinate=Coordinate(29784.355, -61734.665, rotation=2.534306)), Panel(handle="'B2315", blockname="*U6007", wind_zone=0, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(30051.565, -61785.059, rotation=2.534306), original_coordinate=Coordinate(30051.565, -61785.059, rotation=2.534306)), Panel(handle="'B22F7", blockname="*U6007", wind_zone=0, panel_type=PanelType.NorthSouth, subarray=1, coordinate=Coordinate(29963.411, -61788.961, rotation=2.534306), original_coordinate=Coordinate(29963.411, -61788.961, rotation=2.534306)), Panel(handle="'B22D9", blockname="*U6007", wind_zone=0, panel_type=PanelType.NorthSouth, subarray=1, coordinate=Coordinate(29875.258, -61792.862, rotation=2.534306), original_coordinate=Coordinate(29875.258, -61792.862, rotation=2.534306)), Panel(handle="'B22B6", blockname="*U6007", wind_zone=0, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(29787.104, -61796.764, rotation=2.534306), original_coordinate=Coordinate(29787.104, -61796.764, rotation=2.534306)) ] parsed_csv = self.subject.csv() assert_array_equal(parsed_csv, expected_result) def test_csv_parsing_with_fuzzy_wind_zones(self): csv_file = open('test/fixtures/input_dual_tilt_coordinates_fuzzy_wind_zone.csv', 'r') csv_contents = csv_file.read() csv_file.close() self.site.cad_file = csv_contents expected_result = [ Panel(handle="'B247D", blockname="*U6006", wind_zone=0, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(30043.319, -61598.761, rotation=2.534306), original_coordinate=Coordinate(30043.319, -61598.761, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B245F", blockname="*U6006", wind_zone=0, panel_type=PanelType.NorthSouth, subarray=1, coordinate=Coordinate(29955.165, -61602.663, rotation=2.534306), original_coordinate=Coordinate(29955.165, -61602.663, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B2441", blockname="*U6006", wind_zone=0, panel_type=PanelType.NorthSouth, subarray=1, coordinate=Coordinate(29867.012, -61606.565, rotation=2.534306), original_coordinate=Coordinate(29867.012, -61606.565, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B2423", blockname="*U6006", wind_zone=0, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(29778.858, -61610.467, rotation=2.534306), original_coordinate=Coordinate(29778.858, -61610.467, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B2405", blockname="*U6006", wind_zone=0, panel_type=PanelType.EastWest, subarray=1, coordinate=Coordinate(30046.068, -61660.860, rotation=2.534306), original_coordinate=Coordinate(30046.068, -61660.860, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B23E7", blockname="*U6006", wind_zone=0, panel_type=PanelType.Middle, subarray=1, coordinate=Coordinate(29957.914, -61664.762, rotation=2.534306), original_coordinate=Coordinate(29957.914, -61664.762, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B23C9", blockname="*U6006", wind_zone=0, panel_type=PanelType.Middle, subarray=1, coordinate=Coordinate(29869.760, -61668.664, rotation=2.534306), original_coordinate=Coordinate(29869.760, -61668.664, rotation=2.534306), fuzzy_wind_zone=False), Panel(handle="'B23AB", blockname="*U6006", wind_zone=0, panel_type=PanelType.EastWest, subarray=1, coordinate=Coordinate(29781.607, -61672.566, rotation=2.534306), original_coordinate=Coordinate(29781.607, -61672.566, rotation=2.534306), fuzzy_wind_zone=False), Panel(handle="'B238D", blockname="*U6007", wind_zone=0, panel_type=PanelType.EastWest, subarray=1, coordinate=Coordinate(30048.816, -61722.960, rotation=2.534306), original_coordinate=Coordinate(30048.816, -61722.960, rotation=2.534306), fuzzy_wind_zone=False), Panel(handle="'B236F", blockname="*U6007", wind_zone=0, panel_type=PanelType.Middle, subarray=1, coordinate=Coordinate(29960.663, -61726.861, rotation=2.534306), original_coordinate=Coordinate(29960.663, -61726.861, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B2351", blockname="*U6007", wind_zone=0, panel_type=PanelType.Middle, subarray=1, coordinate=Coordinate(29872.509, -61730.763, rotation=2.534306), original_coordinate=Coordinate(29872.509, -61730.763, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B2333", blockname="*U6007", wind_zone=0, panel_type=PanelType.EastWest, subarray=1, coordinate=Coordinate(29784.355, -61734.665, rotation=2.534306), original_coordinate=Coordinate(29784.355, -61734.665, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B2315", blockname="*U6007", wind_zone=0, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(30051.565, -61785.059, rotation=2.534306), original_coordinate=Coordinate(30051.565, -61785.059, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B22F7", blockname="*U6007", wind_zone=0, panel_type=PanelType.NorthSouth, subarray=1, coordinate=Coordinate(29963.411, -61788.961, rotation=2.534306), original_coordinate=Coordinate(29963.411, -61788.961, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B22D9", blockname="*U6007", wind_zone=0, panel_type=PanelType.NorthSouth, subarray=1, coordinate=Coordinate(29875.258, -61792.862, rotation=2.534306), original_coordinate=Coordinate(29875.258, -61792.862, rotation=2.534306), fuzzy_wind_zone=True), Panel(handle="'B22B6", blockname="*U6007", wind_zone=0, panel_type=PanelType.Corner, subarray=1, coordinate=Coordinate(29787.104, -61796.764, rotation=2.534306), original_coordinate=Coordinate(29787.104, -61796.764, rotation=2.534306), fuzzy_wind_zone=True) ] parsed_csv = self.subject.csv() assert_array_equal(parsed_csv, expected_result) def test_power_stations_returns_sites_power_stations_formatted_nicely(self): self.site.power_stations = [ PowerStation( quantity=1, ac_run_length=10, description='Test', id=30, inverters=[ Inverter( model=str(InverterType.SMA.MODEL_12KW.value), sunshade=True, dc_switch=True, strings_per_inverter=4 ) ] ) ] eq_(self.subject.power_stations(), [{ 'power_station_quantity': 1, 'power_station_description': 'Test', 'power_station_id': 30, 'ac_run_length': 10, 'inverter_quantity': 1, 'inverters': [{ 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 4, 'sunshade': True, 'dc_switch': True, 'splice_box': None, }], }]) def test_standalone_inverters_returns_sites_standalone_inverters_formatted_nicely(self): self.site.standalone_inverters = [ StandaloneInverter( id=1, site_id=self.site.id, ac_run_length=10, attachment_point_id=None, inverter=[ Inverter( model=str(InverterType.SMA.MODEL_12KW.value), sunshade=True, dc_switch=True, strings_per_inverter=4 ) ] ) ] eq_(self.subject.standalone_inverters(), [{ 'standalone_inverter_id': 1, 'ac_run_length': 10, 'attachment_point': ('Switch Gear', None), 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 4, 'sunshade': True, 'dc_switch': True, 'splice_box': None }]) def test_power_monitors_returns_sites_power_monitors_formatted_nicely(self): self.site.power_monitors = [ PowerMonitor( id=1, site_id=self.site.id, power_station_id=None) ] eq_(self.subject.power_monitors(), [{ 'monitor_id': 1, 'power_source': ('Switch Gear/External', None) }]) def test_get_user_provided_seismic_anchors(self): self.store.set("user_override_seismic_anchors", json.dumps([{"seismic_anchors": 3, 'panel_id': 2}, {"seismic_anchors": 0, 'panel_id': 4}])) eq_(self.subject.get_user_provided_seismic_anchors(), [ Panel(id=2, seismic_anchors=3), Panel(id=4, seismic_anchors=0) ])