Compare commits
4 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f3d2cf4fa | |||
| f893955616 | |||
| 0b360c9e0e | |||
| 16666d98d0 |
21 changed files with 767 additions and 29 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -1,7 +1,6 @@
|
|||
# Python-generated files
|
||||
__pycache__/
|
||||
*.py[oc]
|
||||
build/
|
||||
dist/
|
||||
wheels/
|
||||
*.egg-info
|
||||
|
|
@ -14,6 +13,10 @@ wheels/
|
|||
uv.lock
|
||||
.python-version
|
||||
|
||||
# docs folders
|
||||
|
||||
docs/build/
|
||||
|
||||
# MacOS things
|
||||
|
||||
.DS_Store*
|
||||
22
README.md
22
README.md
|
|
@ -2,13 +2,16 @@
|
|||
|
||||
or JMKTools for short.
|
||||
|
||||
I don't know if this should be called a library or a set of modules. What it is, is a set of functions that replace calculations that I do on a weekly basis.
|
||||
What it is, is a set of functions that replace calculations that I do on a weekly basis.
|
||||
|
||||
The library is broken into sections, with more being added later, including circuits and pv.
|
||||
The library is broken into sections, including
|
||||
|
||||
Some of these libraries rely on publicly accessible information, including manufacturer data sheets. The libraries that rely on copyrighted information you need to make sure that you have a copy of the standard, code, etc before initializing the software.
|
||||
- general
|
||||
- circuits
|
||||
- grounding
|
||||
- and pv.
|
||||
|
||||
Use the example python notebook to get started.
|
||||
Some of these modulesrely on publicly accessible information, including manufacturer data sheets.
|
||||
|
||||
## What we're missing
|
||||
|
||||
|
|
@ -19,8 +22,15 @@ Tests, I haven't written any real tests for this set of libraries, yet. That wil
|
|||
|
||||
Currently the tools use the CEC, in most cases this will match the NEC, but something we are working on is updating that so we can select from which code version should be used for the calculation.
|
||||
|
||||
Another limitation is the use of SQL databases. This limits its functionality as a module, but my ability with pandas dataframe lookups is very weak. If anyone wants to make the changes and submit a pull request, we can develop that method on a different branch and test it to the main in the near future.
|
||||
|
||||
# Future Features
|
||||
|
||||
There are a lot of different features that I am planning, including building a web app that will allow this tool to be easily used from a browser, but before I get to that the largest feature that I need to figure out is how to install this as a module so that it can be called from any script that you want.
|
||||
- [x] Web app (this is started at [Digital Power Systems Toolbox](http://toolbox.digitalpowersystems.net)
|
||||
- [x] Installable package [The first releases are here](https://git.jmkengineering.com/JMK_Engineering_Inc/JMKTools/releases)
|
||||
- [ ] Add NEC to the calculations
|
||||
- [x] Re-do and add PV functions to the package.
|
||||
- [ ] Detailed documentation (the source is started in this repo)
|
||||
- [ ] Electrical Safety Calculations
|
||||
- [ ] Basic Load flow tools
|
||||
- [ ] Basic Short circuit tools
|
||||
- [ ] Continue developing the DPS Toolbox
|
||||
20
docs/Makefile
Normal file
20
docs/Makefile
Normal file
|
|
@ -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)
|
||||
35
docs/make.bat
Normal file
35
docs/make.bat
Normal file
|
|
@ -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
|
||||
13
docs/source/circuits/index.rst
Normal file
13
docs/source/circuits/index.rst
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Circuit Functions
|
||||
================================
|
||||
|
||||
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
|
||||
.. automodule:: jmktools.circuits
|
||||
:members:
|
||||
44
docs/source/conf.py
Normal file
44
docs/source/conf.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# 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
|
||||
|
||||
|
||||
# Configure autodoc
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('../src/jmktools/'))
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = 'JMK Engineering Python Tools'
|
||||
copyright = '2025, Jeff MacKinnon'
|
||||
author = 'Jeff MacKinnon'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
extensions = ['sphinx.ext.autodoc',]
|
||||
|
||||
|
||||
|
||||
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 = "sphinx_book_theme"
|
||||
html_static_path = ['_static']
|
||||
|
||||
html_title = "JMK Engineering Python Tools Documentation"
|
||||
|
||||
html_theme_options = {
|
||||
"repository_url": "https://git.jmkengineering.com/JMK_Engineering_Inc/JMKTools",
|
||||
"repository_provider": "github",
|
||||
"use_repository_button": True,
|
||||
}
|
||||
12
docs/source/general/index.rst
Normal file
12
docs/source/general/index.rst
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
General Functions
|
||||
================================
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
va
|
||||
|
||||
.. automodule:: jmktools.general
|
||||
:members:
|
||||
17
docs/source/general/va.rst
Normal file
17
docs/source/general/va.rst
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
va - Volt-Amps
|
||||
================
|
||||
|
||||
|
||||
.. function:: va(voltage, current, phases=3)
|
||||
|
||||
:module: src.jmktools.general
|
||||
:param voltage: The voltage of the circuit
|
||||
:type voltage: float
|
||||
:param current: The current of the circuit
|
||||
:type current: float
|
||||
:returns: volt-Amps in VA
|
||||
:rtype: float
|
||||
|
||||
Describe the function
|
||||
|
||||
|
||||
10
docs/source/grounding/index.rst
Normal file
10
docs/source/grounding/index.rst
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
Grounding Functions
|
||||
================================
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
.. automodule:: jmktools.grounding
|
||||
:members:
|
||||
23
docs/source/index.rst
Normal file
23
docs/source/index.rst
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
.. 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 Tools Documentation
|
||||
============================================
|
||||
|
||||
This site is the official documentation for `jmktools <https://git.jmkengineering.com/JMK_Engineering_Inc/JMKTools>`_.
|
||||
|
||||
The package is broken into various modules to keep the functions "clean". Currently they are
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Contents:
|
||||
|
||||
installation
|
||||
general/index
|
||||
pvsolar/index
|
||||
circuits/index
|
||||
grounding/index
|
||||
|
||||
|
||||
12
docs/source/installation.rst
Normal file
12
docs/source/installation.rst
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
Installation
|
||||
==============
|
||||
|
||||
The project releases, complete with release details are found on the `JMK Engineering git site <https://git.jmkengineering.com/JMK_Engineering_Inc/JMKTools/releases>`_. We are also including pypi installable releases `here <https://pypi.org/project/jmktools/>`_.
|
||||
|
||||
To install use ``pip install jmktools``. We recommend using `uv <https://docs.astral.sh/uv/>`_ for managing python projects.
|
||||
|
||||
Once you have it installed you would use:
|
||||
|
||||
``uv init``
|
||||
|
||||
``uv add jmktools``
|
||||
18
docs/source/pvsolar/index.rst
Normal file
18
docs/source/pvsolar/index.rst
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
PV Solar Functions
|
||||
================================
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
voc
|
||||
|
||||
|
||||
.. automodule:: jmktools.pvsolar
|
||||
:members:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
40
docs/source/pvsolar/voc.rst
Normal file
40
docs/source/pvsolar/voc.rst
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
PV Voc Functions
|
||||
================================
|
||||
|
||||
When designing the strings for a PV solar system, the string voltage shall never be higher than the input voltage of the inverter or storage controller. PV panels nameplate voltage is typically shown at the standard testing condition (STC) temperature of 25C. As the outside temperature drops, the open-circuit voltage of the panel will increase.
|
||||
|
||||
To ensure that this voltage doesn't over-voltage the connected equipment, we need to use the minimum site temperature, and the :math:`\beta` of the panel. We will assume that it is -0.5 unless you pass a different value.
|
||||
|
||||
|
||||
|
||||
Temp Adjusted Voc
|
||||
--------------------
|
||||
|
||||
.. function:: temp_adj_Voc(Voc,temp,beta=-0.5,STCtemp = 25)
|
||||
:no-index:
|
||||
|
||||
:module: src.jmktools.pvsolar
|
||||
:param Voc: The open-circuit voltage of the PV Panel
|
||||
:type Voc: float
|
||||
:param temp: The minimum temperature that the panel will be operating.
|
||||
:type temp: float
|
||||
:returns: Adjusted Voc in volts
|
||||
:rtype: float
|
||||
|
||||
The Voc of a panel will increase as the temperature decreases.
|
||||
The datasheet Voc is typically at STC, or 25C. As the temperature decreases this Voc needs to be adjusted.
|
||||
This adjustment is linear based on the beta value with the units %/C.
|
||||
This beta value will be shown as a negative indicating that as the temperature increases, then the Voc will decrease.
|
||||
This Voc decrease results in derating of power during temperature above 25C.
|
||||
|
||||
Voc = The STC panel open circuit voltage
|
||||
temp = The min or max temperature for the PV plant.
|
||||
beta = The panel temperature coefficient. default -0.5%/C, typical values will range from -0.2 to -0.45.
|
||||
|
||||
The adjusted Voc is Voc minus the voltage shift. When the outside temperature is above the STC value then the Vocadj will be lower.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
[project]
|
||||
name = "jmktools"
|
||||
version = "0.1.0"
|
||||
version = "0.2b1"
|
||||
description = "JMK Engineering Python Toolboox"
|
||||
readme = "README.md"
|
||||
license = "AGPL-3.0-or-later"
|
||||
license-files = [
|
||||
"LICENSE",
|
||||
]
|
||||
requires-python = ">=3.14"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"numpy>=2.4.2",
|
||||
"pandas>=3.0.0",
|
||||
|
|
@ -19,3 +19,9 @@ jmktools = "jmktools:main"
|
|||
[build-system]
|
||||
requires = ["uv_build>=0.10.0,<0.11.0"]
|
||||
build-backend = "uv_build"
|
||||
|
||||
[dependency-groups]
|
||||
docs = [
|
||||
"sphinx>=9.1.0",
|
||||
"sphinx-book-theme>=1.1.4",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -228,26 +228,27 @@ cec24table6C = [
|
|||
]
|
||||
|
||||
# TODO - Add tables 6D thru 6K
|
||||
|
||||
# Table 9A/B Internal diameter and cross-sectional areas of various trade conduit and tubing
|
||||
# Only using the internal diameter (ID) for each of these conduits, along with the trade size. This will be used to calculate the area and fill for the various limits per Table 8
|
||||
'''
|
||||
rmc = rigid metal conduit
|
||||
fmc = flexible metal conduit
|
||||
rpvc = rigid PVC
|
||||
db2 = rigid Type EB1 PVC and rigid type DB2/ES2 PVC conduit
|
||||
mlt = metallic liquid tight, flexible conduit
|
||||
nmlt = non-metallic liquid tight conduit
|
||||
emt = electrical metallic tubing
|
||||
ent = electrical non-metallic tubing
|
||||
rtrcips = rigid RTRC conduit marked IPS
|
||||
rtrcid = rigid RTRC conduit marked ID
|
||||
sch40 = HDPE conduit schedule 40
|
||||
sch80 = HDPE conduit schedule 80
|
||||
dr9 = HDPE DR9 conduit
|
||||
dr11 = HDPE DR11 conduit
|
||||
dr13 = HDPE DR13.5 conduit
|
||||
dr15 = HDPE DR15.5 conduit
|
||||
Table 9A/B Internal diameter and cross-sectional areas of various trade conduit and tubing
|
||||
|
||||
Only using the internal diameter (ID) for each of these conduits, along with the trade size. This will be used to calculate the area and fill for the various limits per Table 8
|
||||
|
||||
- rmc = rigid metal conduit
|
||||
- fmc = flexible metal conduit
|
||||
- rpvc = rigid PVC
|
||||
- db2 = rigid Type EB1 PVC and rigid type DB2/ES2 PVC conduit
|
||||
- mlt = metallic liquid tight, flexible conduit
|
||||
- nmlt = non-metallic liquid tight conduit
|
||||
- emt = electrical metallic tubing
|
||||
- ent = electrical non-metallic tubing
|
||||
- rtrcips = rigid RTRC conduit marked IPS
|
||||
- rtrcid = rigid RTRC conduit marked ID
|
||||
- sch40 = HDPE conduit schedule 40
|
||||
- sch80 = HDPE conduit schedule 80
|
||||
- dr9 = HDPE DR9 conduit
|
||||
- dr11 = HDPE DR11 conduit
|
||||
- dr13 = HDPE DR13.5 conduit
|
||||
- dr15 = HDPE DR15.5 conduit
|
||||
'''
|
||||
cec24table9AB = [
|
||||
['size','RMC', 'FMC', 'RPVC', 'DB2', 'LTMC', 'LTNMC','EMT', 'ENT', 'RTRCIPS', 'RTRCID', 'SCH40', 'SCH80', 'DR9','DR11', 'DR13', 'DR15'],
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
from .circuits import *
|
||||
from .general import *
|
||||
from .grounding import *
|
||||
from .pvsolar import *
|
||||
from .tables import *
|
||||
|
||||
def main() -> None:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ by: Jeff MacKinnon
|
|||
email: jeff@jmkengineering.com
|
||||
|
||||
Some General Functions and things
|
||||
|
||||
----------------------------------
|
||||
'''
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
|
|
|||
62
src/jmktools/grounding.py
Normal file
62
src/jmktools/grounding.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
'''
|
||||
JMK Engineering Inc. Python Tools
|
||||
by: Jeff MacKinnon
|
||||
|
||||
email: jeff@jmkengineering.com
|
||||
|
||||
Grounding functions
|
||||
|
||||
'''
|
||||
|
||||
import pandas as pd
|
||||
import math
|
||||
|
||||
|
||||
def resistivity_wenner(spacing,resistance):
|
||||
'''
|
||||
This function calculates the resistivity in ohm-m from the wenner resistance measurements.
|
||||
|
||||
The spacing must be in meters and the resistance in ohms.
|
||||
'''
|
||||
|
||||
rho = 2 * math.pi * spacing * resistance
|
||||
return rho
|
||||
|
||||
def laurent (area,len_conductor,resistivity):
|
||||
'''
|
||||
This function calculates the expected Rg of a grounding system using the Laurent Method, also known as the IEEE 80 Simplified method.
|
||||
|
||||
Rg_area = (soil_resistivity / (4 * sqrt(Area_of_grounding_system))
|
||||
|
||||
Rg_conductors = soil_resistivity / total_buried_conductor_length
|
||||
|
||||
Rg = Rg_area + Rg_conductors
|
||||
|
||||
'''
|
||||
|
||||
rg_area = resistivity / (4 * math.sqrt(area))
|
||||
rg_conductor = resistivity / len_conductor
|
||||
|
||||
rg = rg_area + rg_conductor
|
||||
|
||||
return rg
|
||||
|
||||
def sverak(area,len_conductor,depth,resistivity):
|
||||
'''
|
||||
This is IEEE 80, Equation 57 or Sverak method to calcuate the Rg.
|
||||
|
||||
It is:
|
||||
|
||||
Rg = soil_resistivity*[1/total_buried_conductor_length + {(1/sqrt(20*Area_of_grounding_system)) * (1 + 1/(1+buried_depth_grounding_system * sqrt(20 / Area_of_grounding_system)))}]
|
||||
|
||||
This function breaks the function into three parts to make it easier to read.
|
||||
'''
|
||||
|
||||
sv_part1 = 1/ len_conductor
|
||||
sv_part2 = 1 / math.sqrt(20 * area)
|
||||
sv_part3 = 1 + (1 / (1 + depth * math.sqrt(20 / area)))
|
||||
|
||||
rg = resistivity * (sv_part1 + sv_part2 * sv_part3)
|
||||
|
||||
return rg
|
||||
|
||||
62
src/jmktools/pvsolar.py
Normal file
62
src/jmktools/pvsolar.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
'''
|
||||
JMK Engineering Inc. Python Tools
|
||||
by: Jeff MacKinnon
|
||||
|
||||
email: jeff@jmkengineering.com
|
||||
|
||||
PV Design functions
|
||||
|
||||
'''
|
||||
|
||||
def temp_adj_Voc(Voc,temp,beta=-0.5,STCtemp = 25):
|
||||
|
||||
'''
|
||||
The Voc of a panel will increase as the temperature decreases.
|
||||
The datasheet Voc is typically at STC, or 25C. As the temperature decreases this Voc needs to be adjusted.
|
||||
This adjustment is linear based on the beta value with the units %/C.
|
||||
This beta value will be shown as a negative indicating that as the temperature increases, then the Voc will decrease.
|
||||
This Voc decrease results in derating of power during temperature above 25C.
|
||||
|
||||
Voc = The STC panel open circuit voltage
|
||||
temp = The min or max temperature for the PV plant.
|
||||
beta = The panel temperature coefficient. default -0.5%/C, typical values will range from -0.2 to -0.45.
|
||||
|
||||
The adjusted Voc is Voc minus the voltage shift. When the outside temperature is above the STC value then the Vocadj will be lower.
|
||||
'''
|
||||
|
||||
tempadj = STCtemp - temp #-
|
||||
|
||||
percent_shift = tempadj * beta/100 #+
|
||||
|
||||
|
||||
volt_shift = Voc * percent_shift
|
||||
|
||||
Vocadj = Voc - volt_shift # The voltage adjust is the
|
||||
|
||||
return Vocadj
|
||||
|
||||
|
||||
def panels_per_string(Vmax,Voc,beta=-0.5,temp = 25,STCtemp = 25):
|
||||
|
||||
'''
|
||||
This function calculates the maximum number of panels that a string can have.
|
||||
It will automatically calculate the temperature shifted number when beta and temp are given.
|
||||
|
||||
'''
|
||||
Vocadj = temp_adj_Voc(Voc, temp,beta, STCtemp = 25)
|
||||
|
||||
panels_per_string_max = Vmax // Vocadj
|
||||
|
||||
return int(panels_per_string_max)
|
||||
|
||||
def voltage_per_string(panels,Voc,beta=-0.5,temp = 25,STCtemp = 25):
|
||||
'''
|
||||
This function calculates the temperature adjusted string voltage based on the number of panels, open-circuit voltage (Voc).
|
||||
By default it assumes a beta of -0.5, tem of 25C and a tested STCtemp of 25C.
|
||||
'''
|
||||
|
||||
vocadj = temp_adj_Voc(Voc, temp,beta, STCtemp = 25)
|
||||
|
||||
voltage = vocadj * panels
|
||||
|
||||
return round(voltage,4)
|
||||
|
|
@ -3,6 +3,8 @@ JMK Engineering Inc. Python Library for design and such.
|
|||
by: Jeff MacKinnon
|
||||
|
||||
email: jeff@jmkengineering.com
|
||||
|
||||
This module imports all the various tables as shown in the various standards and codes.
|
||||
'''
|
||||
|
||||
#
|
||||
|
|
|
|||
346
tools.py
Normal file
346
tools.py
Normal file
|
|
@ -0,0 +1,346 @@
|
|||
'''
|
||||
JMK Engineering Inc. Python Library for design and such.
|
||||
by: Jeff MacKinnon
|
||||
|
||||
email: jeff@jmkengineering.com
|
||||
|
||||
Commandline tools for JEPL functions
|
||||
|
||||
'''
|
||||
|
||||
import argparse
|
||||
import jmktools as jmk
|
||||
|
||||
|
||||
#
|
||||
# functions for the functions
|
||||
#
|
||||
|
||||
# General
|
||||
|
||||
def va(args):
|
||||
x = [1,3,None]
|
||||
if args.phases in x:
|
||||
if args.phases == None:
|
||||
phases = 3
|
||||
else:
|
||||
phases = args.phases
|
||||
result = jmk.va(args.voltage, args.current, phases=phases)
|
||||
print ( str(round(result,2))+ "VA")
|
||||
else:
|
||||
print(args.phases)
|
||||
|
||||
def xfmr_sc(args):
|
||||
if args.phases == None:
|
||||
phases = 3
|
||||
elif arg.phases == 1:
|
||||
phases = 1
|
||||
else:
|
||||
phases = 3
|
||||
|
||||
#print(args.kva)
|
||||
#print(args.voltage)
|
||||
#print(args.impedance)
|
||||
|
||||
result = jmk.xfmr_sc(args.kva, args.voltage, args.impedance, phases = phases)
|
||||
print(result)
|
||||
|
||||
|
||||
# Circuits
|
||||
|
||||
def condsize(args):
|
||||
if args.temp == None:
|
||||
temp = 60
|
||||
else:
|
||||
temp = args.temp
|
||||
if args.material == None:
|
||||
material = 'cu'
|
||||
else:
|
||||
material = args.material
|
||||
if args.code == None:
|
||||
code = 'CEC'
|
||||
else:
|
||||
code = args.code
|
||||
if args.raceway == None:
|
||||
raceway = True
|
||||
elif args.raceway == 'n':
|
||||
raceway = False
|
||||
else:
|
||||
raceway = True
|
||||
if args.ambient == None:
|
||||
ambient = 30
|
||||
else:
|
||||
ambient = args.ambient
|
||||
if args.maxsize == None:
|
||||
maxsize = 500
|
||||
else:
|
||||
maxsize = 500
|
||||
if args.type == None:
|
||||
loadtype = None
|
||||
else:
|
||||
valid_load_type = ['normal','xfmr','xfmrp','xfmrs','motor',None]
|
||||
if args.type not in valid_load_type:
|
||||
print(args.type + " is not a valid load_type.")
|
||||
else:
|
||||
loadtype = args.type
|
||||
|
||||
result = jmk.conductor_size(args.current, temp = temp, material = material, code = code, raceway = raceway, max = maxsize, load_type = loadtype )
|
||||
print(result)
|
||||
|
||||
def condamp(args):
|
||||
if args.temp == None:
|
||||
temp = 60
|
||||
else:
|
||||
temp = args.temp
|
||||
if args.material == None:
|
||||
material = 'cu'
|
||||
else:
|
||||
material = args.material
|
||||
if args.code == None:
|
||||
code = 'CEC'
|
||||
else:
|
||||
code = args.code
|
||||
if args.raceway == None:
|
||||
raceway = True
|
||||
elif args.raceway == 'n':
|
||||
raceway = False
|
||||
else:
|
||||
raceway = True
|
||||
if args.ambient == None:
|
||||
ambient = 30
|
||||
else:
|
||||
ambient = args.ambient
|
||||
result = jmk.conductor_ampacity(args.conductor, temp = temp, material = material, code = code, raceway = raceway)
|
||||
print(result)
|
||||
|
||||
def bonding(args):
|
||||
|
||||
if args.material == None:
|
||||
material = 'cu'
|
||||
else:
|
||||
material = args.material
|
||||
if args.code == None:
|
||||
code = 'CEC'
|
||||
else:
|
||||
code = args.code
|
||||
if args.bus == None:
|
||||
bus = False
|
||||
else:
|
||||
bus = args.bus
|
||||
|
||||
result = jmk.bonding_conductor(args.circuit_ampacity, bus = bus, material = material, code = code)
|
||||
print(result)
|
||||
|
||||
|
||||
def voltagedrop(args):
|
||||
|
||||
voltage = args.voltage
|
||||
current = args.current
|
||||
size = args.conductor_size
|
||||
length = args.length
|
||||
if args.phases == None:
|
||||
num_phase = 3
|
||||
elif args.phases == '1':
|
||||
num_phase = 1
|
||||
elif args.phases == '3':
|
||||
num_phase = 3
|
||||
else:
|
||||
print('--phase must be 1 or 2.')
|
||||
if args.material == None:
|
||||
material = 'cu'
|
||||
else:
|
||||
material = args.material
|
||||
if args.runs == None:
|
||||
num_runs = 1
|
||||
else:
|
||||
num_runs = args.runs
|
||||
if args.runs == None:
|
||||
num_runs = 1
|
||||
else:
|
||||
num_runs = args.runs
|
||||
if args.code == None:
|
||||
code = 'CEC'
|
||||
else:
|
||||
code = args.code
|
||||
if args.powerfactor == None:
|
||||
power_factor = 'dc'
|
||||
else:
|
||||
power_factor = args.powerfactor
|
||||
if args.raceway == None:
|
||||
raceway = True
|
||||
elif args.raceway == 'n':
|
||||
raceway = False
|
||||
else:
|
||||
raceway = True
|
||||
|
||||
if args.temp == None:
|
||||
insul_temp = 75
|
||||
else:
|
||||
insul_temp = args.temp
|
||||
|
||||
result = jmk.voltage_drop(voltage, current, size, length, num_phase = num_phase, material = material, num_runs = num_runs, code = code, power_factor = power_factor, raceway = raceway, insul_temp = insul_temp)
|
||||
print(result)
|
||||
|
||||
def conduit_size(args):
|
||||
|
||||
if args.insulation == None:
|
||||
insulation = "RW90"
|
||||
else:
|
||||
insulation = args.insulation
|
||||
if args.voltage == None:
|
||||
voltage = 1000
|
||||
else:
|
||||
voltage = args.voltage
|
||||
if args.jacketed == None:
|
||||
jacketed = False
|
||||
else:
|
||||
jacketed = args.jacketed
|
||||
if args.material == None:
|
||||
material = 'SCH80'
|
||||
else:
|
||||
material = args.material
|
||||
if args.code == None:
|
||||
code = 'CEC'
|
||||
else:
|
||||
code = args.code
|
||||
|
||||
result = jmk.conduit_size(args.num_conductors,args.size,args.bond,insulation=insulation, voltage = voltage, jacketed = jacketed,material=material, code = code)
|
||||
percent_fill = str(round(result[3],2) * 100) + "%" + " fill."
|
||||
print(percent_fill,result[1])
|
||||
|
||||
|
||||
# Solar
|
||||
|
||||
def temp_adj_Voc(args):
|
||||
if args.beta == None:
|
||||
beta = -0.5
|
||||
else:
|
||||
beta = args.beta
|
||||
if args.stctemp == None:
|
||||
stctemp = 25
|
||||
else:
|
||||
stctemp = args.stctemp
|
||||
result = jmk.temp_adj_Voc(args.voc, args.temperature, beta, stctemp)
|
||||
print(str(round(result,2))+"V")
|
||||
|
||||
|
||||
#
|
||||
# Parse the options
|
||||
#
|
||||
|
||||
try:
|
||||
parser = argparse.ArgumentParser()
|
||||
subparsers = parser.add_subparsers(
|
||||
title="tools",
|
||||
help="Commandline Functions"
|
||||
)
|
||||
|
||||
#
|
||||
# This section is for the jepl_general functions
|
||||
#
|
||||
|
||||
# Calcuating VA
|
||||
|
||||
va_parser = subparsers.add_parser("va", help="calculate VA (S)")
|
||||
va_parser.add_argument("voltage", type=float,help="Voltage of the circuit")
|
||||
va_parser.add_argument("current", type=float,help="Current of the circuit.")
|
||||
va_parser.add_argument("-p","--phases", type=int,help="Phases of the circuit. It should be either 1 or 3, and we will assume 3 if it is not used.")
|
||||
va_parser.set_defaults(func=va)
|
||||
|
||||
|
||||
# Calcuating xfmr_sc
|
||||
|
||||
xfmrsc_parser = subparsers.add_parser("xfmr_sc", help="Calculates the secondary short circuit current of a transformer")
|
||||
xfmrsc_parser.add_argument("voltage", type=float,help="Voltage of the circuit")
|
||||
xfmrsc_parser.add_argument("kva", type=float,help="Transformer rating in kVA.")
|
||||
xfmrsc_parser.add_argument("impedance", type=float,help="Transformer impedance in percent Z.")
|
||||
xfmrsc_parser.add_argument("-p","--phases", type=int,help="Phases of the circuit. It should be either 1 or 3, and we will assume 3 if it is not used.")
|
||||
xfmrsc_parser.set_defaults(func=xfmr_sc)
|
||||
|
||||
#
|
||||
# Circuit Tools
|
||||
#
|
||||
|
||||
|
||||
condsize_parser = subparsers.add_parser("condsize", help="Determine the conductor size for a defined current and load type.")
|
||||
condsize_parser.add_argument("current", type=float, help="The current of the circuit.")
|
||||
condsize_parser.add_argument("-t", "--temp", type=int, help="The temperature rating for the insulation, if none included is 60C. default: 60" )
|
||||
condsize_parser.add_argument("-m", "--material", type=str, help="This should be cu or al, for copper or aluminum. If none defined cu will be used.")
|
||||
condsize_parser.add_argument("-c", "--code", type=str, help="Currently this will either be CEC or NEC. default CEC")
|
||||
condsize_parser.add_argument("-r", "--raceway", type=str, help="If the conductors are in a raceway use y for yes and n for no.")
|
||||
condsize_parser.add_argument("-a", "--ambient", type=float, help="Ambient temperature in celsious. default: 30")
|
||||
condsize_parser.add_argument("-x", "--maxsize", type=str, help="Maximum conductor size in AWG/kcmil. default: 500")
|
||||
condsize_parser.add_argument("--type",type=str, help="Load type {}'normal','xfmr','xfmrp','xfmrs','motor',None}, default: None")
|
||||
condsize_parser.set_defaults(func=condsize)
|
||||
|
||||
condamp_parser = subparsers.add_parser("condamp", help="Determine the ampacity of a conductor.")
|
||||
condamp_parser.add_argument("conductor", type=str, help="The conductor size in AWG/kcmil")
|
||||
condamp_parser.add_argument("-t", "--temp", type=int, help="The temperature rating for the insulation, if none included is 60C. default: 60" )
|
||||
condamp_parser.add_argument("-m", "--material", type=str, help="This should be cu or al, for copper or aluminum. If none defined cu will be used.")
|
||||
condamp_parser.add_argument("-c", "--code", type=str, help="Currently this will either be CEC or NEC. default CEC")
|
||||
condamp_parser.add_argument("-r", "--raceway", type=str, help="If the conductors are in a raceway use y for yes and n for no.")
|
||||
condamp_parser.add_argument("-a", "--ambient", type=float, help="Ambient temperature in celsious. default: 30")
|
||||
condamp_parser.set_defaults(func=condamp)
|
||||
|
||||
bonding_parser = subparsers.add_parser("bonding", help="Bonding conductor for the circuit, wire or bus.")
|
||||
bonding_parser.add_argument("circuit_ampacity", type=float, help="Circuit ampacity.")
|
||||
bonding_parser.add_argument("-m", "--material", type=str, help="This should be cu or al, for copper or aluminum. If none defined cu will be used.")
|
||||
bonding_parser.add_argument("-c", "--code", type=str, help="Currently this will either be CEC or NEC. default CEC")
|
||||
bonding_parser.add_argument("-b", "--bus", type=bool, help="Bus or wire bond, bus =True, wire = False.")
|
||||
bonding_parser.set_defaults(func=bonding)
|
||||
|
||||
|
||||
|
||||
voltagedrop_parser = subparsers.add_parser("voltagedrop", help="Determine the voltage drop of a circuit.")
|
||||
voltagedrop_parser.add_argument("voltage", type=float, help="The circuit voltage.")
|
||||
voltagedrop_parser.add_argument("current", type=float, help="The circuit current")
|
||||
voltagedrop_parser.add_argument("conductor_size", type=str, help="The conductor size.")
|
||||
voltagedrop_parser.add_argument("length", type=float, help="The circuit length, in metres.")
|
||||
voltagedrop_parser.add_argument("-t", "--temp", type=int, help="The temperature rating for the insulation, if none included is 60C. default: 75" )
|
||||
voltagedrop_parser.add_argument("-m", "--material", type=str, help="This should be cu or al, for copper or aluminum. If none defined cu will be used.")
|
||||
voltagedrop_parser.add_argument("-c", "--code", type=str, help="Currently this will either be CEC or NEC. default CEC")
|
||||
voltagedrop_parser.add_argument("-r", "--raceway", type=str, help="If the conductors are in a raceway use y for yes and n for no.")
|
||||
voltagedrop_parser.add_argument("-pf","--powerfactor", type=str, help="Power Factor. Valid options DC, 1, 0.9, 0.8. default dc")
|
||||
voltagedrop_parser.add_argument("--phases", type=str, help="Number of phases, 1 or 3, default = 3.")
|
||||
voltagedrop_parser.add_argument("--runs", type=int, help="Number of circuits in parallel, default 1.")
|
||||
voltagedrop_parser.set_defaults(func=voltagedrop)
|
||||
|
||||
|
||||
consize_parser = subparsers.add_parser("conduitsize", help="Calculate the proper conduit size.")
|
||||
consize_parser.add_argument("num_conductors", type=int, help="Number of current carrying conductors, typically 1 to 4.")
|
||||
consize_parser.add_argument("size", type=str, help="Size of the current carrying conductors in AWG or kcmil." )
|
||||
consize_parser.add_argument("bond", type=str, help="Size of the bond conductor, or equipment grounding conductor in AWG or kcmil")
|
||||
consize_parser.add_argument("-i", "--insulation", type=str, help="Insulation type. default RW90")
|
||||
consize_parser.add_argument("-v", "--voltage", type=int, help="Voltage rating of the insulation, 600 or 1000")
|
||||
consize_parser.add_argument("-j", "--jacketed", type=bool, help="Are the conductors jacketed? Default: False")
|
||||
consize_parser.add_argument("-m", "--material", type=str, help="Material or conduit type, ie EMT, ENT, SCH40, etc. Default SCH80")
|
||||
consize_parser.add_argument("-c", "--code", type=str, help="Currently this will either be CEC or NEC. default CEC")
|
||||
consize_parser.set_defaults(func=conduit_size)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Solar Tools
|
||||
#
|
||||
|
||||
tempvoc = subparsers.add_parser("tempVoc", help="Calculate the temperature adjusted Voc of a PV panel.")
|
||||
tempvoc.add_argument("voc", type=float,help="Open circuit voltage of the panel.")
|
||||
tempvoc.add_argument("temperature", type=float, help="Temperature the panel will be at.")
|
||||
tempvoc.add_argument("-b", "--beta", type=float, help="Panel Beta value, if none is added -0.5 will be used.")
|
||||
tempvoc.add_argument("-t", "--stctemp", type=float, help="The STC temp. If none is added 25C will be used.")
|
||||
tempvoc.set_defaults(func=temp_adj_Voc)
|
||||
|
||||
|
||||
|
||||
# This runs the function that was selected with the arguments in the command.
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
|
||||
|
||||
|
||||
except argparse.ArgumentError as e:
|
||||
#log.error("Error parsing arguments")
|
||||
raise e
|
||||
Loading…
Add table
Reference in a new issue