Project
Function
Sample CLI
gway awg find-cable
References
['debug', 'info', 'sql', 'sql.open_connection']
Full Code
def find_cable(
*,
meters: Union[int, str, None] = None,
amps: Union[int, str] = "40",
volts: Union[int, str] = "220",
material: Literal["cu", "al", "?"] = "cu",
max_lines: Union[int, str] = "1",
phases: Literal["1", "3", 1, 3] = "1",
conduit: Optional[Union[str, bool]] = None,
neutral: Union[int, str] = "1"
):
"""Calculate the type of cable needed for an electrical system."""
gw.info(f"Calculating AWG for {meters=} {amps=} {volts=} {material=}")
with gw.sql.open_connection(autoload=True) as cursor:
# Convert inputs
amps = int(amps)
meters = int(meters)
volts = int(volts)
max_lines = int(max_lines)
phases = int(phases)
neutral = int(neutral)
# Validate inputs
assert amps >= 20, "Min. charger load is 20 Amps."
assert meters >= 1, "Consider at least 1 meter of cable."
assert 110 <= volts <= 460, "Volt range is 110-460."
assert material in ("cu", "al", "?"), "Material must be cu, al or ?."
assert phases in (1, 3), "Allowed phases 1 or 3."
# Choose voltage drop formula based on phases
if phases == 3:
expr = "sqrt(3) * (:meters / line_num) * (k_ohm_km / 1000)"
else:
expr = "2 * (:meters / line_num) * (k_ohm_km / 1000)"
# Fetch all ampacity-qualified cables ordered by AWG descending (largest cable first)
sql = f"""
SELECT awg_size, line_num, {expr} AS vdrop
FROM awg_cable_size
WHERE (material = :material OR :material = '?')
AND ((amps_75c >= :amps AND :amps > 100)
OR (amps_60c >= :amps AND :amps <= 100))
AND line_num <= :max_lines
ORDER BY awg_size DESC
"""
params = {
"amps": amps,
"meters": meters,
"material": material,
"volts": volts,
"max_lines": max_lines,
}
gw.debug(f"AWG find-cable SQL candidates: {sql.strip()}, params: {params}")
cursor.execute(sql, params)
candidates = cursor.fetchall()
gw.debug(f"AWG find-cable candidates fetched: {candidates}")
# Iterate and pick first cable within voltage drop threshold (3%)
for awg_size, line_num, vdrop in candidates:
perc = vdrop / volts
gw.debug(f"Evaluating AWG={awg_size}, lines={line_num}, vdrop={vdrop:.6f}, vdperc={perc*100:.4f}%")
if perc <= 0.03:
awg_res = AWG(awg_size)
cables = line_num * (phases + neutral)
result = {
"awg": str(awg_res),
"amps": amps,
"meters": meters,
"lines": line_num,
"vdrop": vdrop,
"vend": volts - vdrop,
"vdperc": perc * 100,
"cables": cables,
"cable_m": cables * meters,
}
if conduit:
if conduit is True:
conduit = "emt"
fill = find_conduit(awg_res, cables, conduit=conduit)
result["conduit"] = conduit
result["pipe_in"] = fill["size_in"]
gw.debug(f"Selected cable result: {result}")
return result
# If no suitable cable found, return 'n/a'
gw.debug("No cable found within voltage drop limit (3%). Returning 'n/a'.")
return {"awg": "n/a"}