diff --git a/.gitignore b/.gitignore index b8a936a..d791662 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ test* __pycache__ *.db +/docs/build/ \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..dc1312a --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..872241a --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,27 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'JMK Engineering Python Library' +copyright = '2025, Jeff MacKinnon' +author = 'Jeff MacKinnon' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ['_templates'] +exclude_patterns = [] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..fc877a5 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,17 @@ +.. JMK Engineering Python Library documentation master file, created by + sphinx-quickstart on Wed Jan 1 14:10:19 2025. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +JMK Engineering Python Library documentation +============================================ + +Add your content using ``reStructuredText`` syntax. See the +`reStructuredText `_ +documentation for details. + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + diff --git a/example_notebook.ipynb b/example_notebook.ipynb index 5e3d90e..e789e44 100644 --- a/example_notebook.ipynb +++ b/example_notebook.ipynb @@ -791,63 +791,6 @@ "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, @@ -857,95 +800,57 @@ "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" + "53\n" ] } ], "source": [ "db_result_index = 3\n", "\n", + "test = ' WHERE DB2 > 200'\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", + " cur.execute('SELECT \"Trade Size\" from \"Table9\"'+test)\n", + " table = cur.fetchone()\n", + " conduits = np.array(table)[0]\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)" + "print(conduits)\n" ] }, { - "cell_type": "code", - "execution_count": 20, + "cell_type": "markdown", "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')" + "The Conduit sizing module is designed to size conduits based on the CEC values for the various conductor sizes with insulation.\n", + "\n", + "It returns two values, the trade size (diameter) in mm and the text for a cable/conduit schedule" ] }, { "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, + "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "0\n" + "16 is the trade size\n", + "16mm SCH80 is the value you can use in your cable/conduit schedule.\n" ] } ], "source": [ - "x = np.array(valid_material)\n", - "row = np.where(x == 'RMC')[0][0]\n", - "print(row)" + "conduit_size = jmk.conduit_size(4,'12','12')\n", + "\n", + "print(str(conduit_size[0]) + \" is the trade size\")\n", + "print(conduit_size[1] + \" is the value you can use in your cable/conduit schedule.\")" ] } ], diff --git a/jepl/Tables/Z462-Tables/Z46215-table1A.csv b/jepl/Tables/Z462-Tables/Z46215-table1A.csv new file mode 100644 index 0000000..ad6450f --- /dev/null +++ b/jepl/Tables/Z462-Tables/Z46215-table1A.csv @@ -0,0 +1,7 @@ +Voltage,Movable LA SI,Movable LA Imperial,Fixed LA SI,Fixed LA Imperial,Restricted SI,Restricted Imperial +50,Not Specified,Not Specified,Not Specified,Not Specified,Not Specified,Not Specified +150,3,120,1,42,0,0 +750,3,120,1,42,0.3,12 +15000,3,120,1.5,60,0.7,26 +35000,3,120,1.8,72,0.8,31 +46000,3,120,2.5,96,0.8,33 diff --git a/jepl/Tables/Z462-Tables/Z46215-table1B.csv b/jepl/Tables/Z462-Tables/Z46215-table1B.csv new file mode 100644 index 0000000..0625f3b --- /dev/null +++ b/jepl/Tables/Z462-Tables/Z46215-table1B.csv @@ -0,0 +1,7 @@ +Voltage,Movable LA SI,Movable LA Imperial,Fixed LA SI,Fixed LA Imperial,Restricted SI,Restricted Imperial +50,Not Specified,Not Specified,Not Specified,Not Specified,Not Specified,Not Specified +300,3,120,1,42,0,0 +1000,3,120,1,42,0.3,12 +5000,3,120,1.5,60,0.4,17 +15000,3,120,1.5,60,0.7,26 +45000,3,120,2.5,96,0.8,33 diff --git a/jepl/jepl.py b/jepl/jepl.py index 2039d7e..fdde28e 100644 --- a/jepl/jepl.py +++ b/jepl/jepl.py @@ -5,8 +5,11 @@ by: Jeff MacKinnon email: jeff@jmkengineering.com ''' import sys +from .jepl_general import * from .jeplpv import * from .jepl_circuits import * +from .jepl_templates import * +from .jepl_safety import * def Test(): print( "JMK Python Module works! !") diff --git a/jepl/jepl_circuits.py b/jepl/jepl_circuits.py index 7c01622..361bc68 100644 --- a/jepl/jepl_circuits.py +++ b/jepl/jepl_circuits.py @@ -496,8 +496,8 @@ def bonding_conductor(conductor_ampacity,bus=False,material='cu',code = 'CEC'): return bond_size -## This doesn't work yet, but its getting there -def conduit_size(num_cc,cc_con,bond,material='EMT'): +## This doesn't work yet, but its getting +def conduit_size(num_cc,cc_con,bond,material='SCH80'): # Calculate fill requirements based on Table 8 @@ -582,35 +582,34 @@ def conduit_size(num_cc,cc_con,bond,material='EMT'): # Total conductor area area_conductors = cc_area + bond_area + #print(area_conductors) min_trade_area = area_conductors / percent_fill # The minimum area of the conduit + #print(min_trade_area) + parameter = ' WHERE ' + material + ' > ' + str(min_trade_area) + try: with sqlite3.connect("jepl-cec21.db") as con: cur = con.cursor() - cur.execute('SELECT * from "Table9"') - table = cur.fetchall() - conduits = np.array(table) + cur.execute('SELECT "Trade Size" from "Table9"'+ parameter ) + table = cur.fetchone() + conduit = 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] + result_raw = conduit[0] + result_name = str(conduit[0]) + 'mm ' + material - return result + return result_raw,result_name - def cable_schedule_naming(conductor_size,conductors,runs = 1,bond='BOND'): diff --git a/jepl/jepl_general.py b/jepl/jepl_general.py new file mode 100644 index 0000000..de823b2 --- /dev/null +++ b/jepl/jepl_general.py @@ -0,0 +1,30 @@ +''' +JMK Engineering Inc. Python Library for design and such. +by: Jeff MacKinnon + +email: jeff@jmkengineering.com + +Some General Functions and things + +''' +import pandas as pd +import numpy as np +import math +import sqlite3 + + +def va(voltage, current,phases=3): + '''Calculate the Volt-Amp of a circuit + ''' + + if phases == 3: + va = (math.pi * voltage * current) + + elif phases == 1: + vs = voltage * current + else: + print("Phases needs to be 1 or 3 for now.") + + return va + + diff --git a/jepl/jepl_safety.py b/jepl/jepl_safety.py new file mode 100644 index 0000000..64388dd --- /dev/null +++ b/jepl/jepl_safety.py @@ -0,0 +1,129 @@ +''' +JMK Engineering Inc. Python Library for design and such. +by: Jeff MacKinnon + +email: jeff@jmkengineering.com + +Electrical Safety + +These functions are used to calculate boundaries, etc. + +''' + +import sqlite3 + +def limitedApproach(voltage,fixed=False,DC=False,unitsSI=True,year=2015): + + if year == 2015: + database = "jepl-z46215.db" + + if DC == True: + try: + with sqlite3.connect(database) as con: + cur = con.cursor() + + cur.execute('SELECT * FROM "Table1B" WHERE "Voltage" > ? ', (voltage,)) + row = cur.fetchone() + + except sqlite3.OperationalError as e: + print(e) + else: + try: + with sqlite3.connect(database) as con: + cur = con.cursor() + + cur.execute('SELECT * FROM "Table1A" WHERE "Voltage" > ? ', (voltage,)) + row = cur.fetchone() + + except sqlite3.OperationalError as e: + print(e) + + + if (fixed == False) & (unitsSI == True): + column = 1 + elif (fixed == False) & (unitsSI == False): + column = 2 + elif (fixed == True) & (unitsSI == True): + column = 3 + elif (fixed == True) & (unitsSI == False): + column = 4 + + distance = row[column] + return(distance) + +def restrictedApproach(voltage,DC=False,unitsSI=True,year=2015): + + if year == 2015: + database = "jepl-z46215.db" + + if DC == True: + try: + with sqlite3.connect(database) as con: + cur = con.cursor() + + cur.execute('SELECT * FROM "Table1B" WHERE "Voltage" > ? ', (voltage,)) + row = cur.fetchone() + + except sqlite3.OperationalError as e: + print(e) + else: + try: + with sqlite3.connect(database) as con: + cur = con.cursor() + + cur.execute('SELECT * FROM "Table1A" WHERE "Voltage" > ? ', (voltage,)) + row = cur.fetchone() + + except sqlite3.OperationalError as e: + print(e) + + + if (unitsSI == True): + column = 5 + else: + column = 6 + + distance = row[column] + return(distance) + + + +def gloveClass(voltage,DC=False): + ''' + The glove class is based on the ASTM standard D120. + ''' + + if DC == True: + if voltage <= 750: + gloveclass = '00' + elif voltage <= 1500: + gloveclass = '0' + elif voltage <= 11250: + gloveclass = '1' + elif voltage <= 25500: + gloveclass = '2' + elif voltage <= 39750: + gloveclass = '3' + elif voltage <= 54000: + gloveclass = '4' + else: + gloveclass = "Voltage too High" + + + else: + if voltage <= 500: + gloveclass = '00' + elif voltage <= 1000: + gloveclass = '0' + elif voltage <= 7500: + gloveclass = '1' + elif voltage <= 17000: + gloveclass = '2' + elif voltage <= 26500: + gloveclass = '3' + elif voltage <= 36000: + gloveclass = '4' + else: + gloveclass = "Voltage too High" + + return(gloveclass) \ No newline at end of file diff --git a/jepl/jepl_templates.py b/jepl/jepl_templates.py new file mode 100644 index 0000000..3b8a831 --- /dev/null +++ b/jepl/jepl_templates.py @@ -0,0 +1,84 @@ +''' +JMK Engineering Inc. Python Library for design and such. +by: Jeff MacKinnon + +email: jeff@jmkengineering.com + +Template Generation + +These functions are used to create labels, reports, etc. + +''' +from .jepl_safety import * + +def af_label(equipment,working_distance,incident_energy,af_boundary,energy_level,voltage, author="Jeff MacKinnon",warning="warning",project="Arc Flash Warning Label",project_num="2500",DC=False,fixedElectrode = True, SI=True,project_year=2015,test=False): + + ''' + This function is for printing a single label with all the information in the function above. Include the units (in, Vac, Vdc, ft, m, mm, etc.) in the values. All values are strings. + ''' + + from datetime import date + date = date.today() + revdate = date.strftime("%m/%d/%Y") + + if DC == True: + voltage_units = " Vdc" + else: + voltage_units = " Vac" + + label_voltage = str(voltage) + voltage_units + + + + glove_class = gloveClass(voltage,DC=DC) + limited_approach = limitedApproach(voltage,fixed=fixedElectrode,DC=DC,unitsSI=SI,year=project_year) + restricted_approach = restrictedApproach(voltage,DC=DC,unitsSI=SI,year=project_year) + + + if warning =="warning": + warning_colour = '242,85,31' + warning_text = '\warning WARNING' + elif warning == "danger": + warning_colour = '242,85,31' # This colour needs to change + warning_text = '\warning DANGER' + else: + warning_colour = '255,255,255' # This colour needs to change + warning_text = '' + + from jinja2 import Environment, FileSystemLoader + + environment = Environment( block_start_string = '\BLOCK{', + block_end_string = '}', + variable_start_string = '\VAR((', + variable_end_string = '))', + comment_start_string = '\#{', + comment_end_string = '}', + line_comment_prefix = '%#', + loader=FileSystemLoader("jepl/templates/") + ) + template = environment.get_template("template-label-ArcFlash.tex") + + if test == True: + filename = "test"+str(date) + "-"+project_num+"-label-ArcFlash.tex" + else: + filename = str(date) + "-"+project_num+"-label-ArcFlash.tex" + content = template.render( + DATE = revdate, + EQUIPMENT = equipment, + WORKING_DISTANCE = working_distance, + INCIDENT_ENERGY = incident_energy, + AF_BOUNDARY = af_boundary, + ENERGY_LEVEL = energy_level, + VOLTAGE = label_voltage, + LIMITED_APPROACH = limited_approach, + RESTRICTED_APPROACH = restricted_approach, + GLOVE_CLASS = glove_class, + AUTHOR = author, + TITLE = project, + WARNING_COLOUR = warning_colour, + WARNING_TEXT = warning_text, + + + ) + with open(filename, mode="w", encoding="utf-8") as message: + message.write(content) diff --git a/jepl/jeplinit.py b/jepl/jeplinit.py index 82d4021..c663892 100644 --- a/jepl/jeplinit.py +++ b/jepl/jeplinit.py @@ -59,6 +59,11 @@ CEC21_database = [ ] create_database('jepl-cec21.db',CEC21_database) +Z46215_database = [ + ['jepl-z46215.db','Table1A',location+'Tables/Z462-Tables/Z46215-table1A.csv'], + ['jepl-z46215.db','Table1B',location+'Tables/Z462-Tables/Z46215-table1B.csv'], + ] +create_database('jepl-z46215.db',Z46215_database) cable_database = [ diff --git a/jepl/templates/static/logo.png b/jepl/templates/static/logo.png new file mode 100644 index 0000000..6a71a0c Binary files /dev/null and b/jepl/templates/static/logo.png differ diff --git a/jepl/templates/template-label-ArcFlash.tex b/jepl/templates/template-label-ArcFlash.tex new file mode 100644 index 0000000..9b9360f --- /dev/null +++ b/jepl/templates/template-label-ArcFlash.tex @@ -0,0 +1,127 @@ + +\documentclass[12pt]{article} +\pagestyle{empty} + +%\usepackage[utf8]{inputenc} +\usepackage{tikz} +\usepackage{fourier} +\usepackage{geometry} + +\usepackage{anyfontsize} +\usepackage{multicol} + +\usepackage[export]{adjustbox} + + +\usetikzlibrary{calc} + +\geometry{% + paperheight=105mm, + paperwidth=160mm, + top=2mm, + bottom=2mm, + right=2mm, + left=2mm, +} + + +\usepackage{layout} + \setlength{\parindent}{1pt} + + +\title{\VAR((TITLE))} +\date{\VAR((DATE))} +\author{\VAR((AUTHOR))} + + + +\begin{document} + +%% Header Warning Banner %% +\definecolor{warningcolour}{RGB}{\VAR((WARNING_COLOUR))} + + + % \thispagestyle{empty} + \begin{tikzpicture}[overlay, remember picture]% + \node[] + at ($(current page.north)+(0cm, -13mm)$) {% + \begin{tikzpicture} + \node[rectangle, + draw = white, + text = black, + minimum width = \textwidth, + minimum height = 23mm, + fill = warningcolour] (r) at (0,0) + {% + \fontfamily{phv}\fontsize{36pt}{40pt}\selectfont \textbf{\VAR((WARNING_TEXT))}% This is the warning text + }; + \end{tikzpicture} + }; +% This is the main message + \node[% + text width=\textwidth, + align=center, + ] + at ($(current page.center) + (0cm,18mm)$) {% + \fontfamily{phv} + \fontsize{20pt}{100pt}\selectfont + \textbf{% + Arc Flash and Shock Hazard Present \\ + Appropriate PPE Required + } + }; +% This is the study Results + \node[text width=\textwidth, align=center] + at ($(current page.center) + (5mm,-7mm)$) {% + \begin{multicols}{2} + \textbf{ARC FLASH PROTECTION} \\ + \vspace{3mm} + + \begin{tabular}{ l l } + Working Distance & \textbf{\VAR((WORKING_DISTANCE))} \\ % Working Distance + Incident Energy & \textbf{\VAR((INCIDENT_ENERGY)) cal/cm$^2$} \\ % Incident Energy Value + Arc Flash Hazard Boundary & \textbf{\VAR((AF_BOUNDARY))} \\ % Arc Flash Boundary + Energy Level & \textbf{Level \VAR((ENERGY_LEVEL))} \\ % Energy Level + \end{tabular} + + \columnbreak + + \textbf{SHOCK PROTECTION}\\ + \vspace{4mm} + + \begin{tabular}{ l l } + Shock Hazard & \textbf{\VAR((VOLTAGE))} \\ % Shock voltage + Limited Approach & \textbf{\VAR((LIMITED_APPROACH))} \\ % Limited Approach boundary + Restricted Approach & \textbf{\VAR((RESTRICTED_APPROACH))} \\ % Restricted Approach boundard + Glove Class & \textbf{\VAR((GLOVE_CLASS))} \\ % Glove Class + \end{tabular} + + \end{multicols} + }; +% This is the equipment information + \node[text width=0.5\textwidth, align=left] + at ($(current page.west) + (45mm,-40mm)$) {% + \large + Equipment: \textbf{\VAR((EQUIPMENT))} \\ + + Date: \textbf{\VAR((DATE))} \\ + \vspace{2mm} + \scriptsize + Arc flash analysis by \VAR((AUTHOR)) + + }; +% This is the logo + \node[text width=0.5\textwidth, align=right] + at ($(current page.east) + (-40mm,-4cm)$) {% + \includegraphics[width=70mm,left]{jepl/templates/static/logo.png} + }; + + \end{tikzpicture} + + +\newpage + + + + +\end{document}