import unittest from unittest.mock import MagicMock from helix.calculators.ebom_calculator import EbomCalculator, ModuleType from helix.constants.inverter_type import InverterType from helix.constants.parts import * from helix.constants.system_type import SystemType from test.test_helpers import assert_dictionary_equal class EbomCalculatorTest(unittest.TestCase): def setUp(self): self.user_values = MagicMock() self.subject = EbomCalculator(self.user_values, 171, 98) def test_computes_ebom_without_aux_plugs(self): self.user_values.power_stations.return_value = [ { 'power_station_id': '1', 'power_station_description': 'Panel Board 1', 'power_station_quantity': 1, 'ac_run_length': 109, 'inverter_quantity': 2, 'inverters': [ { 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 2, 'sunshade': False, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_15KW, 'strings_per_inverter': 5, 'sunshade': True, 'dc_switch': False, } ] }, { 'power_station_id': '2', 'power_station_description': 'Panel Board 2', 'power_station_quantity': 3, 'ac_run_length': 355, 'inverter_quantity': 4, 'inverters': [ { 'model': InverterType.SMA.MODEL_20KW, 'strings_per_inverter': 6, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 7, 'sunshade': False, 'dc_switch': False, } ] } ] self.user_values.standalone_inverters.return_value = [ { 'standalone_inverter_id': 'key_1', 'ac_run_length': 57, 'model': InverterType.SMA.MODEL_20KW, 'strings_per_inverter': 5, 'sunshade': True, 'dc_switch': False, 'attachment_point': ('Panel Board 1', '1') }, { 'standalone_inverter_id': 'key_2', 'ac_run_length': 200, 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 3, 'sunshade': False, 'dc_switch': True, 'attachment_point': ('Switch Gear', None) }, { 'standalone_inverter_id': 'key_3', 'ac_run_length': 0, 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 3, 'sunshade': False, 'dc_switch': False, 'attachment_point': ('Panel Board 1', '1') }, ] self.user_values.power_monitors.return_values = [] self.user_values.system_type.return_value = SystemType.dualTilt self.user_values.module_type.return_value = ModuleType.Cell96 expected_output = { flat_washer: 100, star_washer: 12, channel_nut: 16, phillips_screw: 12, hex_nut_quarter_20: 8, hex_nut_three_eighths_16: 100, flat_washer_quarter_inch: 8, flat_washer_6: 12, hex_bolt_quarter_20: 8, stump: 102+181, wire_clip_large: 2907, cable_support_lid: 368, cable_support: 368, rear_skirt: -140, dc_switch_bracket: 2, front_legs: 23, back_legs: 23, inverter_link: 46, inverter_rail: 23, sma_20kw_inverter: 4, sunshade: 2, hex_bolt_3_4: 50, panel_board_4: 4, ac_inverter_bracket: 3, rubber_foot: 69, harness_3_string_fm: 13, harness_3_string_mf: 13, harness_2_string_fm: 3, harness_2_string_mf: 3, harness_4_string_fm: 15, harness_4_string_mf: 15, harness_ac_inner: 8, harness_ac_outer: 8, sma_24kw_inverter: 9, sma_12kw_inverter: 3, sma_15kw_inverter: 1, comm_cable: 12, dc_switch_box: 2, hex_bolt_1_2: 362, whip_tray: 19, ac_switch: 3, ac_splice_box: 2, ethernet_plug: 12.600000000000001, mounting_back_plate: 23, sunshade_bolt: 4, sunshade_washer: 4, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_ebom_with_delta_inverters(self): self.user_values.standalone_inverters.return_value = [ { 'standalone_inverter_id': 'key_1', 'ac_run_length': 57, 'model': InverterType.DELTA.MODEL_36KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, 'splice_box': True, 'attachment_point': ('Switch Gear', None) }, { 'standalone_inverter_id': 'key_2', 'ac_run_length': 200, 'model': InverterType.DELTA.MODEL_42KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, 'splice_box': False, 'attachment_point': ('Switch Gear', None) }, { 'standalone_inverter_id': 'key_3', 'ac_run_length': 0, 'model': InverterType.DELTA.MODEL_60KW, 'strings_per_inverter': 12, 'sunshade': False, 'dc_switch': False, 'splice_box': True, 'attachment_point': ('Switch Gear', None) }, ] self.user_values.system_type.return_value = SystemType.singleTilt self.user_values.module_type.return_value = ModuleType.Cell96 expected_output = { stump: 65, wire_clip_large: 513, cable_support_lid: 0, cable_support: 0, rear_skirt: 0, rubber_foot: 9, delta_inverter_leg: 9, harness_4_string_mf: 4, harness_4_string_fm: 4, delta_36kw_inverter: 1, delta_42kw_inverter: 1, delta_60kw_inverter: 1, delta_splice_box: 2, delta_kit_inverter_mount: 3, delta_kit_inverter_mount_dt: 0 } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_ebom_with_delta_inverters_dual_tilt(self): self.user_values.standalone_inverters.return_value = [ { 'standalone_inverter_id': 'key_1', 'ac_run_length': 0, 'model': InverterType.DELTA.MODEL_42KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, 'splice_box': False, 'attachment_point': ('Switch Gear', None) }, ] self.user_values.system_type.return_value = SystemType.dualTilt self.user_values.module_type.return_value = ModuleType.Cell96 expected_output = { stump: 0, wire_clip_large: 171, cable_support_lid: 0, cable_support: 0, rear_skirt: 0, rubber_foot: 3, delta_inverter_leg: 3, harness_4_string_mf: 2, harness_4_string_fm: 2, delta_42kw_inverter: 1, delta_kit_inverter_mount: 0, delta_kit_inverter_mount_dt: 1, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_ebom_with_aux_plugs(self): self.user_values.power_stations.return_value = [ { 'power_station_description': 'Panel Board 1', 'power_station_id': 'panel_board_uuid_1', 'power_station_quantity': 1, 'ac_run_length': 0, 'inverter_quantity': 2, 'inverters': [ { 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 2, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_15KW, 'strings_per_inverter': 5, 'sunshade': False, 'dc_switch': False, } ] }, { 'power_station_description': 'Panel Board 2', 'power_station_id': 'panel_board_uuid_2', 'power_station_quantity': 2, 'ac_run_length': 0, 'inverter_quantity': 4, 'inverters': [ { 'model': InverterType.SMA.MODEL_20KW, 'strings_per_inverter': 6, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 7, 'sunshade': False, 'dc_switch': True, } ] }, { 'power_station_description': 'Panel Board 2 (aux)', 'power_station_id': 'panel_board_uuid_2_aux', 'power_station_quantity': 1, 'monitor_id': 'foo', 'ac_run_length': 0, 'inverter_quantity': 4, 'inverters': [ { 'model': InverterType.SMA.MODEL_20KW, 'strings_per_inverter': 6, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 7, 'sunshade': False, 'dc_switch': True, } ] } ] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Panel Board 2 (aux)', 'panel_board_uuid_2_aux') }] self.user_values.system_type.return_value = SystemType.dualTilt self.user_values.module_type.return_value = ModuleType.Cell96 # 9 dc switches expected_output = { flat_washer: 76, channel_nut: 20, hex_nut_quarter_20: 36, hex_nut_three_eighths_16: 102, flat_washer_quarter_inch: 36, hex_bolt_quarter_20: 36, monitor_controller_480_v: 1, stump: 84, dc_switch_bracket: 9, front_legs: 19, back_legs: 19, inverter_link: 38, inverter_rail: 19, sma_20kw_inverter: 3, sunshade: 6, hex_bolt_3_4: 64, panel_board_4: 2, panel_board_4_aux: 1, panel_board_2: 1, rubber_foot: 57, harness_3_string_fm: 10, harness_3_string_mf: 10, harness_2_string_fm: 2, harness_2_string_mf: 2, harness_4_string_fm: 15, harness_4_string_mf: 15, harness_ac_inner: 8, harness_ac_outer: 6, sma_24kw_inverter: 9, sma_12kw_inverter: 1, sma_15kw_inverter: 1, comm_cable: 11, dc_switch_box: 9, hex_bolt_1_2: 297, whip_tray: 14, mounting_back_plate: 19, wire_clip_large: 2394, cable_support: 270, cable_support_lid: 270, rear_skirt: -103, ethernet_plug: 7.2, monitor_power_plug: 1, sunshade_bolt: 12, sunshade_washer: 12, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_ebom_with_aux_plugs_on_switchgear(self): self.user_values.power_stations.return_value = [ { 'power_station_description': 'Panel Board 1', 'power_station_id': 'panel_board_uuid_1', 'power_station_quantity': 1, 'ac_run_length': 0, 'inverter_quantity': 2, 'inverters': [ { 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 2, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_15KW, 'strings_per_inverter': 5, 'sunshade': False, 'dc_switch': False, } ] }, { 'power_station_description': 'Panel Board 2', 'power_station_id': 'panel_board_uuid_2', 'power_station_quantity': 3, 'ac_run_length': 0, 'inverter_quantity': 4, 'inverters': [ { 'model': InverterType.SMA.MODEL_20KW, 'strings_per_inverter': 6, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 7, 'sunshade': False, 'dc_switch': True, } ] } ] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Switch Gear/External', None) }] self.user_values.system_type.return_value = SystemType.dualTilt self.user_values.module_type.return_value = ModuleType.Cell96 # 9 dc switches expected_output = { flat_washer: 76, channel_nut: 20, hex_nut_quarter_20: 36, hex_nut_three_eighths_16: 102, flat_washer_quarter_inch: 36, hex_bolt_quarter_20: 36, monitor_controller_480_v: 1, stump: 84, dc_switch_bracket: 9, front_legs: 19, back_legs: 19, inverter_link: 38, inverter_rail: 19, sma_20kw_inverter: 3, sunshade: 6, hex_bolt_3_4: 64, panel_board_4: 3, panel_board_2: 1, rubber_foot: 57, harness_3_string_fm: 10, harness_3_string_mf: 10, harness_2_string_fm: 2, harness_2_string_mf: 2, harness_4_string_fm: 15, harness_4_string_mf: 15, harness_ac_inner: 8, harness_ac_outer: 6, sma_24kw_inverter: 9, sma_12kw_inverter: 1, sma_15kw_inverter: 1, comm_cable: 10, dc_switch_box: 9, hex_bolt_1_2: 297, whip_tray: 14, mounting_back_plate: 19, wire_clip_large: 2394, cable_support: 270, cable_support_lid: 270, rear_skirt: -103, ethernet_plug: 7.2, monitor_power_plug: 1, sunshade_bolt: 12, sunshade_washer: 12, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_ebom_with_aux_plugs_on_switchgear_on_pseries_dual_tilt(self): self.user_values.power_stations.return_value = [ { 'power_station_description': 'Panel Board 1', 'power_station_id': 'panel_board_uuid_1', 'power_station_quantity': 1, 'ac_run_length': 0, 'inverter_quantity': 2, 'inverters': [ { 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 2, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_15KW, 'strings_per_inverter': 5, 'sunshade': False, 'dc_switch': False, } ] }, { 'power_station_description': 'Panel Board 2', 'power_station_id': 'panel_board_uuid_2', 'power_station_quantity': 3, 'ac_run_length': 0, 'inverter_quantity': 4, 'inverters': [ { 'model': InverterType.SMA.MODEL_20KW, 'strings_per_inverter': 6, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 7, 'sunshade': False, 'dc_switch': True, } ] } ] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Switch Gear/External', None) }] self.user_values.system_type.return_value = SystemType.dualTilt self.user_values.module_type.return_value = ModuleType.PSeries # 9 dc switches expected_output = { flat_washer: 132, channel_nut: 20, hex_nut_quarter_20: 36, hex_nut_three_eighths_16: 130, flat_washer_quarter_inch: 36, hex_bolt_quarter_20: 36, monitor_controller_480_v: 1, stump: 84, dc_switch_bracket: 9, front_legs: 19, back_legs: 19, inverter_link: 38, inverter_rail: 19, sma_20kw_inverter: 3, sunshade: 6, hex_bolt_3_4: 106, panel_board_4: 3, panel_board_2: 1, rubber_foot: 57, harness_3_string_fm: 10, harness_3_string_mf: 10, harness_2_string_fm: 2, harness_2_string_mf: 2, harness_4_string_fm: 15, harness_4_string_mf: 15, harness_ac_inner: 8, harness_ac_outer: 6, sma_24kw_inverter: 9, sma_12kw_inverter: 1, sma_15kw_inverter: 1, comm_cable: 10, dc_switch_box: 9, hex_bolt_1_2: 297, whip_tray: 14, mounting_back_plate: 19, wire_clip_large: 2394, cable_support: 270, cable_support_lid: 270, rear_skirt: -103, ethernet_plug: 7.2, monitor_power_plug: 1, fuseshade: 14, screw_12_24x1_25: 28, fuseshade_brace: 14, sunshade_bolt: 12, sunshade_washer: 12, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_ebom_with_power_monitor_DELTA_brand(self): self.user_values.inverter_brands.return_value = [{'inverter_brand_id':2}] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Switch Gear/External', None) }] self.user_values.system_type.return_value = SystemType.singleTilt self.user_values.module_type.return_value = ModuleType.Cell96 expected_output = { monitor_power_plug: 1, stump: 0, cable_support: 0, cable_support_lid: 0, rear_skirt: 0, monitor_controller_480_v:1, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_ebom_with_power_monitor_SMA_brand(self): self.user_values.inverter_brands.return_value = [{'inverter_brand_id':1}] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Switch Gear/External', None) }] self.user_values.system_type.return_value = SystemType.singleTilt self.user_values.module_type.return_value = ModuleType.Cell96 expected_output = { monitor_power_plug: 1, stump: 0, cable_support: 0, cable_support_lid: 0, rear_skirt: 0, monitor_controller_480_v:1, flat_washer: 4, channel_nut: 4, hex_nut_three_eighths_16: 2, front_legs: 1, back_legs: 1, inverter_link: 2, inverter_rail: 1, rubber_foot: 3, hex_bolt_1_2: 9, mounting_back_plate: 1, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_ebom_with_aux_plugs_on_switchgear_on_pseries_single_tilt(self): self.user_values.power_stations.return_value = [ { 'power_station_description': 'Panel Board 1', 'power_station_id': 'panel_board_uuid_1', 'power_station_quantity': 1, 'ac_run_length': 0, 'inverter_quantity': 2, 'inverters': [ { 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 2, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_15KW, 'strings_per_inverter': 5, 'sunshade': False, 'dc_switch': False, } ] }, { 'power_station_description': 'Panel Board 2', 'power_station_id': 'panel_board_uuid_2', 'power_station_quantity': 3, 'ac_run_length': 0, 'inverter_quantity': 4, 'inverters': [ { 'model': InverterType.SMA.MODEL_20KW, 'strings_per_inverter': 6, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 7, 'sunshade': False, 'dc_switch': True, } ] } ] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Switch Gear/External', None) }] self.user_values.system_type.return_value = SystemType.singleTilt self.user_values.module_type.return_value = ModuleType.PSeries # 9 dc switches expected_output = { flat_washer: 132, channel_nut: 20, hex_nut_quarter_20: 36, hex_nut_three_eighths_16: 130, flat_washer_quarter_inch: 36, hex_bolt_quarter_20: 36, monitor_controller_480_v: 1, stump: 84, dc_switch_bracket: 9, front_legs: 19, back_legs: 19, inverter_link: 24, inverter_rail: 19, inverter_link_long: 7, inverter_link_short: 7, sma_20kw_inverter: 3, sunshade: 6, hex_bolt_3_4: 106, panel_board_4: 3, panel_board_2: 1, rubber_foot: 57, harness_3_string_fm: 10, harness_3_string_mf: 10, harness_2_string_fm: 2, harness_2_string_mf: 2, harness_4_string_fm: 15, harness_4_string_mf: 15, harness_ac_inner: 8, harness_ac_outer: 6, sma_24kw_inverter: 9, sma_12kw_inverter: 1, sma_15kw_inverter: 1, comm_cable: 10, dc_switch_box: 9, hex_bolt_1_2: 297, whip_tray: 14, mounting_back_plate: 19, wire_clip_large: 2394, cable_support: 694, cable_support_lid: 694, rear_skirt: -264, ethernet_plug: 7.2, monitor_power_plug: 1, fuseshade: 14, screw_12_24x1_25: 28, fuseshade_brace: 14, sunshade_bolt: 12, sunshade_washer: 12, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_monitor_type_with_aux_plugs(self): self.user_values.power_stations.return_value = [ { 'power_station_description': 'Panel Board 1', 'power_station_id': 'panel_board_uuid_1', 'power_station_quantity': 1, 'ac_run_length': 0, 'inverter_quantity': 2, 'inverters': [ { 'model': InverterType.SMA.MODEL_12KW, 'strings_per_inverter': 2, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_15KW, 'strings_per_inverter': 5, 'sunshade': False, 'dc_switch': False, } ] }, { 'power_station_description': 'Panel Board 2', 'power_station_id': 'panel_board_uuid_2', 'power_station_quantity': 2, 'ac_run_length': 0, 'inverter_quantity': 4, 'inverters': [ { 'model': InverterType.SMA.MODEL_20KW, 'strings_per_inverter': 6, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 7, 'sunshade': False, 'dc_switch': True, } ] }, { 'power_station_description': 'Panel Board 2 (aux)', 'power_station_id': 'panel_board_uuid_2_aux', 'power_station_quantity': 1, 'monitor_id': 'foo', 'ac_run_length': 0, 'inverter_quantity': 4, 'inverters': [ { 'model': InverterType.SMA.MODEL_20KW, 'strings_per_inverter': 6, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': True, 'dc_switch': True, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 8, 'sunshade': False, 'dc_switch': False, }, { 'model': InverterType.SMA.MODEL_24KW, 'strings_per_inverter': 7, 'sunshade': False, 'dc_switch': True, } ] } ] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Panel Board 2 (aux)', 'panel_board_uuid_2_aux') }] self.user_values.system_type.return_value = SystemType.dualTilt # 9 dc switches expected_output_480 = { flat_washer: 76, channel_nut: 20, hex_nut_quarter_20: 36, hex_nut_three_eighths_16: 102, flat_washer_quarter_inch: 36, hex_bolt_quarter_20: 36, monitor_controller_480_v: 1, stump: 84, dc_switch_bracket: 9, front_legs: 19, back_legs: 19, inverter_link: 38, inverter_rail: 19, sma_20kw_inverter: 3, sunshade: 6, hex_bolt_3_4: 64, panel_board_4: 2, panel_board_4_aux: 1, panel_board_2: 1, rubber_foot: 57, harness_3_string_fm: 10, harness_3_string_mf: 10, harness_2_string_fm: 2, harness_2_string_mf: 2, harness_4_string_fm: 15, harness_4_string_mf: 15, harness_ac_inner: 8, harness_ac_outer: 6, sma_24kw_inverter: 9, sma_12kw_inverter: 1, sma_15kw_inverter: 1, comm_cable: 11, dc_switch_box: 9, hex_bolt_1_2: 297, whip_tray: 14, mounting_back_plate: 19, wire_clip_large: 2394, cable_support: 270, cable_support_lid: 270, rear_skirt: -103, ethernet_plug: 7.2, monitor_power_plug: 1, sunshade_bolt: 12, sunshade_washer: 12, } expected_output_240 = { flat_washer: 72, channel_nut: 16, hex_nut_quarter_20: 36, hex_nut_three_eighths_16: 100, flat_washer_quarter_inch: 36, hex_bolt_quarter_20: 36, monitor_controller_240_v: 1, stump: 84, dc_switch_bracket: 9, front_legs: 18, back_legs: 18, inverter_link: 36, inverter_rail: 18, sma_20kw_inverter: 3, sunshade: 6, hex_bolt_3_4: 64, panel_board_4: 3, panel_board_2: 1, rubber_foot: 54, harness_3_string_fm: 10, harness_3_string_mf: 10, harness_2_string_fm: 2, harness_2_string_mf: 2, harness_4_string_fm: 15, harness_4_string_mf: 15, harness_ac_inner: 8, harness_ac_outer: 6, sma_24kw_inverter: 9, sma_12kw_inverter: 1, sma_15kw_inverter: 1, comm_cable: 10, dc_switch_box: 9, hex_bolt_1_2: 288, whip_tray: 14, mounting_back_plate: 18, wire_clip_large: 2394, cable_support: 270, cable_support_lid: 270, rear_skirt: -103, ethernet_plug: 7.2, sunshade_bolt: 12, sunshade_washer: 12, } self.user_values.module_type.return_value = ModuleType.Cell96 self.subject = EbomCalculator(self.user_values, 171, 98, 306) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_480) self.subject = EbomCalculator(self.user_values, 171, 98, 400) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_480) self.subject = EbomCalculator(self.user_values, 171, 98, 304) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_240) self.subject = EbomCalculator(self.user_values, 171, 98, 100) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_240) self.user_values.module_type.return_value = ModuleType.Cell128 self.subject = EbomCalculator(self.user_values, 171, 98, 230) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_480) self.subject = EbomCalculator(self.user_values, 171, 98, 400) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_480) self.subject = EbomCalculator(self.user_values, 171, 98, 229) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_240) self.subject = EbomCalculator(self.user_values, 171, 98, 100) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_240) def test_computes_monitor_type_with_aux_plugs_on_switchgear(self): self.user_values.power_stations.return_value = [] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Switch Gear/External', None) }] self.user_values.system_type.return_value = SystemType.dualTilt # 9 dc switches expected_output_480 = { flat_washer: 4, channel_nut: 4, hex_nut_three_eighths_16: 2, monitor_controller_480_v: 1, stump: 0, front_legs: 1, back_legs: 1, inverter_link: 2, inverter_rail: 1, rubber_foot: 3, hex_bolt_1_2: 9, mounting_back_plate: 1, cable_support: 0, cable_support_lid: 0, rear_skirt: 0, monitor_power_plug: 1, } expected_output_480_pseries = { flat_washer: 4, channel_nut: 4, hex_nut_three_eighths_16: 2, monitor_controller_480_v: 1, stump: 0, front_legs: 1, back_legs: 1, inverter_link: 2, inverter_rail: 1, rubber_foot: 3, hex_bolt_1_2: 9, mounting_back_plate: 1, cable_support: 0, cable_support_lid: 0, rear_skirt: 0, monitor_power_plug: 1, } expected_output_240 = { monitor_controller_240_v: 1, stump: 0, cable_support: 0, cable_support_lid: 0, rear_skirt: 0 } expected_output_240_pseries = { stump: 0, cable_support_lid: 0, cable_support: 0, rear_skirt: 0, monitor_controller_240_v: 1, } self.user_values.module_type.return_value = ModuleType.Cell96 self.subject = EbomCalculator(self.user_values, 171, 98, 306) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_480) self.subject = EbomCalculator(self.user_values, 171, 98, 304) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_240) self.user_values.module_type.return_value = ModuleType.Cell128 self.subject = EbomCalculator(self.user_values, 171, 98, 230) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_480) self.subject = EbomCalculator(self.user_values, 171, 98, 300) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_480) self.subject = EbomCalculator(self.user_values, 171, 98, 229) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_240) self.subject = EbomCalculator(self.user_values, 171, 98, 104) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_240) self.user_values.module_type.return_value = ModuleType.PSeries self.subject = EbomCalculator(self.user_values, 171, 98, 286) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_480_pseries) self.subject = EbomCalculator(self.user_values, 171, 98, 300) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_480_pseries) self.subject = EbomCalculator(self.user_values, 171, 98, 285) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_240_pseries) self.subject = EbomCalculator(self.user_values, 171, 98, 104) assert_dictionary_equal(self.subject.compute_ebom(), expected_output_240_pseries) def test_computes_ebom_with_power_monitor_DELTA_brand(self): self.user_values.inverter_brands.return_value = [{'inverter_brand_id':2}] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Switch Gear/External', None) }] self.user_values.system_type.return_value = SystemType.singleTilt self.user_values.module_type.return_value = ModuleType.Cell96 expected_output = { monitor_power_plug: 1, stump: 0, cable_support: 0, cable_support_lid: 0, rear_skirt: 0, monitor_controller_480_v: 1, ethernet_plug: 2, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output) def test_computes_ebom_with_power_monitor_SMA_brand(self): self.user_values.inverter_brands.return_value = [{'inverter_brand_id':1}] self.user_values.power_monitors.return_value = [{ 'monitor_id': 'foo', 'power_source': ('Switch Gear/External', None) }] self.user_values.system_type.return_value = SystemType.singleTilt self.user_values.module_type.return_value = ModuleType.Cell96 expected_output = { monitor_power_plug: 1, stump: 0, cable_support: 0, cable_support_lid: 0, rear_skirt: 0, monitor_controller_480_v:1, flat_washer: 4, channel_nut: 4, hex_nut_three_eighths_16: 2, front_legs: 1, back_legs: 1, inverter_link: 2, inverter_rail: 1, rubber_foot: 3, hex_bolt_1_2: 9, mounting_back_plate: 1, } assert_dictionary_equal(self.subject.compute_ebom(), expected_output)