From 46956cc66d0842bb89604acf6ae9d9fcea779cf2 Mon Sep 17 00:00:00 2001 From: Jeff MacKinnon Date: Thu, 9 Jan 2025 18:18:33 -0400 Subject: [PATCH] Adding conduit sizing --- example_notebook.ipynb | 224 ++++++++++++++++++++++ jepl/Tables/CEC-Tables/CEC21-table9.csv | 15 ++ jepl/jepl_circuits.py | 240 +++++++++++++++++++++++- jepl/jeplinit.py | 2 +- 4 files changed, 478 insertions(+), 3 deletions(-) create mode 100644 jepl/Tables/CEC-Tables/CEC21-table9.csv diff --git a/example_notebook.ipynb b/example_notebook.ipynb index 0df9f91..5e3d90e 100644 --- a/example_notebook.ipynb +++ b/example_notebook.ipynb @@ -723,6 +723,230 @@ "cell_type": "markdown", "metadata": {}, "source": [] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "not\n" + ] + } + ], + "source": [ + "if 11 > 11:\n", + " print (\"greater\")\n", + "else:\n", + " print(\"not\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you know the conductor size, this function will return the ampacity." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "30" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jmk.conductor_ampacity(12, temp = 75, material = 'al', code = 'CEC', raceway = False, ambient = 30)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'10'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jmk.bonding_conductor(jmk.conductor_ampacity(12, temp = 75, material = 'al', code = 'CEC', raceway = False, ambient = 30),bus=False,material='al',code = 'CEC')" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "wire_size = [\n", + " ['14',2.08],\n", + " ['12',3.31],\n", + " ['10',5.26],\n", + " ['8',8.37],\n", + " ['6',13.3],\n", + " ['4',21.2],\n", + " ['3',26.7],\n", + " ['2',33.6],\n", + " ['1',42.4],\n", + " ['1/0',53.5],\n", + " ['2/0',67.4],\n", + " ['3/0',85],\n", + " ['4/0',107],\n", + " ['250',127],\n", + " ['300',152],\n", + " ['350',177],\n", + " ['400',203],\n", + " ['500',253],\n", + " ['600',304],\n", + " ['700',355],\n", + " ['800',405],\n", + " ['900',456],\n", + " ['1000',507],\n", + " ['1250',633],\n", + " ['1500',760],\n", + " ['1750',887],\n", + " ['2000',1010]]\n", + "\n", + "\n", + "#df = pd.DataFrame(wire_size, columns=[\"wire\",'area'])\n", + "\n", + "\n", + "x = np.array(wire_size)\n", + "row = np.where(x == '12')[0][0]\n", + "\n", + "\n", + "print(row)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[None 167.0 307.0 507.0 792.0 1140.0 2027.0 2951.0 4560.0 6138.0 7870.0\n", + " 12439.0 17613.0 31225.0]\n" + ] + } + ], + "source": [ + "db_result_index = 3\n", + "\n", + "try:\n", + " with sqlite3.connect(\"jepl-cec21.db\") as con:\n", + " cur = con.cursor()\n", + " cur.execute('SELECT * from \"Table9\"')\n", + " table = cur.fetchall()\n", + " conduits = np.array(table)\n", + "\n", + "except sqlite3.OperationalError as e:\n", + " print(e)\n", + "\n", + "column = conduits[ :,db_result_index]\n", + "print(column)\n", + "#x = np.array(column)\n", + "#row = np.where(x = 200)[0][0]\n", + "\n", + "#print(row)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "'>=' not supported between instances of 'NoneType' and 'float'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Input \u001b[1;32mIn [20]\u001b[0m, in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mjmk\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconduit_size\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m4\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m12\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m12\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Business\\JMKEngineering\\Engineering\\Active\\TEP Group\\2425_TEP_Shubie-tower-project\\eng\\resources\\JEPL\\jepl\\jepl_circuits.py:602\u001b[0m, in \u001b[0;36mconduit_size\u001b[1;34m(num_cc, cc_con, bond, material)\u001b[0m\n\u001b[0;32m 599\u001b[0m column \u001b[38;5;241m=\u001b[39m conduits[ :,db_result_index]\n\u001b[0;32m 601\u001b[0m x \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray(column)\n\u001b[1;32m--> 602\u001b[0m row \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mwhere(\u001b[43mx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m>\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mmin_trade_area\u001b[49m)[\u001b[38;5;241m0\u001b[39m][\u001b[38;5;241m0\u001b[39m]\n\u001b[0;32m 604\u001b[0m \u001b[38;5;28mprint\u001b[39m(row)\n\u001b[0;32m 606\u001b[0m result \u001b[38;5;241m=\u001b[39m conduits[row][\u001b[38;5;241m0\u001b[39m]\n", + "\u001b[1;31mTypeError\u001b[0m: '>=' not supported between instances of 'NoneType' and 'float'" + ] + } + ], + "source": [ + "jmk.conduit_size(4,'12','12')" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "valid_material = ['RMC', # Rigid Metal Conduit\n", + " 'FMC', # Flexible Metal Conduit\n", + " 'RPVC', # Rigid PVC\n", + " 'EB1', # Type EB1\n", + " 'DB2', # Type DB2\n", + " 'LTMC', # Liquid Tight Metal Conduit\n", + " 'LTNMC', # Liquid Tight non-metallic conduit\n", + " 'EMT', # electrical metallic tubing\n", + " 'ENT', # electrical non-metallic tubing\n", + " 'SCH40', # HDPE Schedule 40\n", + " 'SCH80', # HDPE Schedule 80\n", + " #'DR9', # HDPE DR9\n", + " #'DR11', # HDPE DR11\n", + " #'DR135', # HDPE DR13.5\n", + " #'DR155' # HDPE DR15.5\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n" + ] + } + ], + "source": [ + "x = np.array(valid_material)\n", + "row = np.where(x == 'RMC')[0][0]\n", + "print(row)" + ] } ], "metadata": { diff --git a/jepl/Tables/CEC-Tables/CEC21-table9.csv b/jepl/Tables/CEC-Tables/CEC21-table9.csv new file mode 100644 index 0000000..baeb9ef --- /dev/null +++ b/jepl/Tables/CEC-Tables/CEC21-table9.csv @@ -0,0 +1,15 @@ +Trade Size,RMC,FMC,RPVC,EB1,DB2,LTMC,LTNMC,EMT,ENT,SCH40,SCH80 +12,,71,,,,119,114,,,, +16,202,198,167,,,196,188,186,167,169,128 +21,354,334,307,,,341,328,330,304,307,246 +27,573,507,507,,,549,527,539,506,507,418 +35,985,792,792,,,965,937,940,894,898,760 +41,1336,1140,1140,,,1257,1257,1288,1230,1233,1054 +53,2199,2027,2027,2027,2027,2068,2098,2132,2057,2057,1796 +63,3139,3167,2951,,,3116,,3783,,2935,2549 +78,4839,4560,4560,4560,4560,4776,,5701,,4553,4002 +91,6458,6207,6138,6138,6138,6207,,7451,,, +103,8311,8107,7870,7870,7870,8107,,9503,,7895,7023 +129,13039,,12439,12538,12538,,,,,12451,11169 +155,18811,,17613,17613,17613,,,,,18027,16029 +200,,,31225,,,,,,,31303, diff --git a/jepl/jepl_circuits.py b/jepl/jepl_circuits.py index b036cc2..7c01622 100644 --- a/jepl/jepl_circuits.py +++ b/jepl/jepl_circuits.py @@ -376,12 +376,248 @@ def conductor_size(current, temp = 75, material = 'cu', code = 'CEC', raceway = return [conductor_size,num_parallel] +def conductor_ampacity(conductor, temp = 75, material = 'cu', code = 'CEC', raceway = True, ambient = 30): + + ''' + Calculates the ampacity of a conductor size and material using code tables. + + ''' + + material = material.upper() + code = code.upper() + valid_temp = [60,75,90] + valid_temp_str = [str(x) for x in valid_temp] + valid_code = ['CEC', + ] + valid_material = ['CU', + 'AL', + ] + + if temp == 90: + conductor_current_index = 3 + elif temp == 75: + conductor_current_index = 2 + else: + conductor_current_index = 1 + + if (code == 'CEC') & (material == 'CU') & (raceway == False): # CEC Table 1 + try: + with sqlite3.connect("jepl-cec21.db") as con: + cur = con.cursor() + cur.execute('SELECT * FROM "Table1" WHERE "size" = ? ', (conductor,)) + max_conductor_current = cur.fetchone() + conductor_ampacity = max_conductor_current[conductor_current_index] + + except sqlite3.OperationalError as e: + print(e) + + elif (code == 'CEC') & (material == 'CU') & (raceway == True): # CEC Table 2 + try: + with sqlite3.connect("jepl-cec21.db") as con: + cur = con.cursor() + cur.execute('SELECT * FROM "Table2" WHERE "size" = ? ', (conductor,)) + max_conductor_current = cur.fetchone() + conductor_ampacity = max_conductor_current[conductor_current_index] + + except sqlite3.OperationalError as e: + print(e) + + elif (code =='CEC') & (material =='AL') & (raceway == False): # CEC Table 3 + try: + with sqlite3.connect("jepl-cec21.db") as con: + cur = con.cursor() + cur.execute('SELECT * FROM "Table3" WHERE "size" = ? ', (conductor,)) + max_conductor_current = cur.fetchone() + conductor_ampacity = max_conductor_current[conductor_current_index] + + except sqlite3.OperationalError as e: + print(e) + + elif (code =='CEC') & (material =='AL') & (raceway == True): # CEC Table 4 + try: + with sqlite3.connect("jepl-cec21.db") as con: + cur = con.cursor() + cur.execute('SELECT * FROM "Table4" WHERE "size" = ? ', (conductor,)) + max_conductor_current = cur.fetchone() + conductor_ampacity = max_conductor_current[conductor_current_index] + + except sqlite3.OperationalError as e: + print(e) + + elif (code =='NEC') & (material =='CU'): + return (' I haven\'t created this table yet') + elif (code =='NEC') & (material =='AL'): + return (' I haven\'t created this table yet') + else: + return ('The variables were\'t right, but I\'m a loss to why.') + + return conductor_ampacity + +def bonding_conductor(conductor_ampacity,bus=False,material='cu',code = 'CEC'): + + ''' + This function + + ''' + + material = material.upper() + code = code.upper() + valid_code = ['CEC', + ] + valid_material = ['CU', + 'AL', + ] + + if (material == 'CU') & (bus == False): + db_index = 1 + elif (material == 'AL') & (bus == False): + db_index = 3 + elif (material == 'CU') & (bus == True): + db_index = 2 + elif (material == 'AL') & (bus == True): + db_index = 4 + else: + return ('The variables were\'t right, but I\'m a loss to why.') + + if (code == 'CEC'): + try: + with sqlite3.connect("jepl-cec21.db") as con: + cur = con.cursor() + cur.execute('SELECT * FROM "Table16" WHERE "current" >= ? ', (conductor_ampacity,)) + bond_result = cur.fetchone() + bond_size = bond_result[db_index] + + except sqlite3.OperationalError as e: + print(e) + + else: + return ('The variables were\'t right, but I\'m a loss to why.') + + return bond_size + + +## This doesn't work yet, but its getting there +def conduit_size(num_cc,cc_con,bond,material='EMT'): + + # Calculate fill requirements based on Table 8 + + valid_material = ['RMC', # Rigid Metal Conduit + 'FMC', # Flexible Metal Conduit + 'RPVC', # Rigid PVC + 'EB1', # Type EB1 + 'DB2', # Type DB2 + 'LTMC', # Liquid Tight Metal Conduit + 'LTNMC', # Liquid Tight non-metallic conduit + 'EMT', # electrical metallic tubing + 'ENT', # electrical non-metallic tubing + 'SCH40', # HDPE Schedule 40 + 'SCH80', # HDPE Schedule 80 + #'DR9', # HDPE DR9 + #'DR11', # HDPE DR11 + #'DR135', # HDPE DR13.5 + #'DR155' # HDPE DR15.5 + ] + + + + if material not in valid_material: + return print(material + " is not a valid material. I should be 'al' or 'cu'.") + + import numpy as np + x = np.array(valid_material) + db_result_index = np.where(x == material)[0][0] + + if num_cc == 1: + percent_fill = 0.53 + elif num_cc == 2: + percent_fill = 0.31 + else: + percent_fill = 0.4 + + # Wire Size and diameter + + wire_size = [ + # ['tradesize',area mm^2] + ['14',2.08], + ['12',3.31], + ['10',5.26], + ['8',8.37], + ['6',13.3], + ['4',21.2], + ['3',26.7], + ['2',33.6], + ['1',42.4], + ['1/0',53.5], + ['2/0',67.4], + ['3/0',85], + ['4/0',107], + ['250',127], + ['300',152], + ['350',177], + ['400',203], + ['500',253], + ['600',304], + ['700',355], + ['800',405], + ['900',456], + ['1000',507], + ['1250',633], + ['1500',760], + ['1750',887], + ['2000',1010] + ] + + # Calculate the area of current carrying conductors + + x = np.array(wire_size) + row = np.where(x == cc_con)[0][0] + current_carrying_conductor_area = wire_size[row][1] + cc_area = current_carrying_conductor_area * num_cc + + # Bond Area + + row = np.where(x == bond)[0][0] + bond_area = wire_size[row][1] + + # Total conductor area + + area_conductors = cc_area + bond_area + + min_trade_area = area_conductors / percent_fill # The minimum area of the conduit + + + try: + with sqlite3.connect("jepl-cec21.db") as con: + cur = con.cursor() + cur.execute('SELECT * from "Table9"') + table = cur.fetchall() + conduits = np.array(table) + + except sqlite3.OperationalError as e: + print(e) + + column = conduits[ :,db_result_index] + + x = np.array(column) + row = np.where(x >= min_trade_area)[0][0] + + print(row) + + result = conduits[row][0] + + + return result + + + + + def cable_schedule_naming(conductor_size,conductors,runs = 1,bond='BOND'): + ''' Converts the conductor size from the above functions to something that can be added to a database/schedule. ''' - if conductor_size == '1/0' or conductor_size == '2/0' or conductor_size == '3/0' or conductor_size == '4/0': unit = "AWG" @@ -392,7 +628,7 @@ def cable_schedule_naming(conductor_size,conductors,runs = 1,bond='BOND'): if bond == 'BOND': bondtext = bond - elif int(bond_size) > 24: + elif int(bond) > 24: bondtext = '#' + str(bond) + 'kcmil' else: bondtext = '#' + str(bond) + 'AWG' diff --git a/jepl/jeplinit.py b/jepl/jeplinit.py index 5c33caf..82d4021 100644 --- a/jepl/jeplinit.py +++ b/jepl/jeplinit.py @@ -54,6 +54,7 @@ CEC21_database = [ ['jepl-cec21.db','Table2',location+'Tables/CEC-Tables/CEC21-table2.csv'], ['jepl-cec21.db','Table3',location+'Tables/CEC-Tables/CEC21-table3.csv'], ['jepl-cec21.db','Table4',location+'Tables/CEC-Tables/CEC21-table4.csv'], + ['jepl-cec21.db','Table9',location+'Tables/CEC-Tables/CEC21-table9.csv'], ['jepl-cec21.db','Table16',location+'Tables/CEC-Tables/CEC21-table16.csv'], ] create_database('jepl-cec21.db',CEC21_database) @@ -63,7 +64,6 @@ create_database('jepl-cec21.db',CEC21_database) cable_database = [ ['jepl-cable.db','SW-Spec 25055',location+'Tables/Manufacturer/SW-Spec-25055.csv'], ['jepl-cable.db','SW-Spec 25051',location+'Tables/Manufacturer/SW-Spec-25051.csv'], - ] create_database('jepl-cable.db',cable_database)