mirror of
https://github.com/RichieCahill/dotfiles.git
synced 2026-04-17 13:08:19 -04:00
173 lines
5.0 KiB
Python
173 lines
5.0 KiB
Python
from enum import Enum
|
|
import math
|
|
|
|
|
|
class TemperatureUnit(Enum):
|
|
CELSIUS = "c"
|
|
FAHRENHEIT = "f"
|
|
KELVIN = "k"
|
|
|
|
|
|
class Temperature:
|
|
def __init__(
|
|
self,
|
|
temperature: float,
|
|
unit: TemperatureUnit = TemperatureUnit.CELSIUS,
|
|
) -> None:
|
|
"""
|
|
Args:
|
|
temperature (float): Temperature in degrees Celsius
|
|
unit (TemperatureUnit, optional): Temperature unit. Defaults to TemperatureUnit.CELSIUS.
|
|
"""
|
|
unit_modifier = {
|
|
TemperatureUnit.CELSIUS: 1,
|
|
TemperatureUnit.FAHRENHEIT: 0.5556,
|
|
TemperatureUnit.KELVIN: 1.8,
|
|
}
|
|
self.temperature = temperature * unit_modifier[unit]
|
|
|
|
def __float__(self) -> float:
|
|
return self.temperature
|
|
|
|
|
|
class LengthUnit(Enum):
|
|
METERS = "m"
|
|
FEET = "ft"
|
|
INCHES = "in"
|
|
|
|
|
|
class Length:
|
|
def __init__(self, length: float, unit: LengthUnit):
|
|
self.meters = self._convert_to_meters(length, unit)
|
|
|
|
def _convert_to_meters(self, length: float, unit: LengthUnit) -> float:
|
|
thing = {
|
|
LengthUnit.METERS: 1,
|
|
LengthUnit.FEET: 0.3048,
|
|
LengthUnit.INCHES: 0.0254,
|
|
}
|
|
test = thing.get(unit)
|
|
if test:
|
|
return length * test
|
|
raise ValueError(f"Unsupported unit: {unit}")
|
|
|
|
def __float__(self):
|
|
return self.meters
|
|
|
|
def feet(self) -> float:
|
|
return self.meters * 3.2808
|
|
|
|
|
|
class MaterialType(Enum):
|
|
COPPER = "copper"
|
|
ALUMINUM = "aluminum"
|
|
CCA = "cca"
|
|
SILVER = "silver"
|
|
GOLD = "gold"
|
|
|
|
|
|
def get_material_resistivity(
|
|
material: MaterialType,
|
|
temperature: Temperature = Temperature(20.0),
|
|
) -> float:
|
|
material_info = {
|
|
MaterialType.COPPER: (1.724e-8, 0.00393),
|
|
MaterialType.ALUMINUM: (2.908e-8, 0.00403),
|
|
MaterialType.CCA: (2.577e-8, 0.00397),
|
|
MaterialType.SILVER: (1.632e-8, 0.00380),
|
|
MaterialType.GOLD: (2.503e-8, 0.00340),
|
|
}
|
|
|
|
base_resistivity, temp_coefficient = material_info[material]
|
|
return base_resistivity * (1 + temp_coefficient * float(temperature))
|
|
|
|
|
|
def calculate_awg_diameter_mm(gauge: int) -> float:
|
|
"""
|
|
Calculate wire diameter in millimeters for a given AWG gauge.
|
|
Formula: diameter = 0.127 * 92^((36-gauge)/39)
|
|
Where:
|
|
- 0.127mm is the diameter of AWG 36
|
|
- 92 is the ratio of diameters between AWG 0000 and AWG 36
|
|
- 39 is the number of steps between AWG 0000 and AWG 36
|
|
"""
|
|
return round(0.127 * 92 ** ((36 - gauge) / 39), 3)
|
|
|
|
|
|
def calculate_wire_area_m2(gauge: int) -> float:
|
|
"""Calculate the area of a wire in square meters.
|
|
|
|
Args:
|
|
gauge (int): The AWG (American Wire Gauge) number of the wire
|
|
|
|
Returns:
|
|
float: The area of the wire in square meters
|
|
"""
|
|
return math.pi * (calculate_awg_diameter_mm(gauge) / 2000) ** 2
|
|
|
|
|
|
def calculate_resistance_per_meter(gauge: int) -> float:
|
|
"""Calculate the resistance per meter of a wire.
|
|
|
|
Args:
|
|
gauge (int): The AWG (American Wire Gauge) number of the wire
|
|
|
|
Returns:
|
|
float: The resistance per meter of the wire
|
|
"""
|
|
return get_material_resistivity(MaterialType.COPPER) / calculate_wire_area_m2(gauge)
|
|
|
|
|
|
def voltage_drop(
|
|
gauge: int,
|
|
material: MaterialType,
|
|
length: Length,
|
|
current_a: float,
|
|
) -> float:
|
|
resistivity = get_material_resistivity(material)
|
|
resistance_per_meter = resistivity / calculate_wire_area_m2(gauge)
|
|
total_resistance = resistance_per_meter * float(length) * 2 # round-trip
|
|
return total_resistance * current_a
|
|
|
|
|
|
print(
|
|
voltage_drop(
|
|
gauge=10,
|
|
material=MaterialType.CCA,
|
|
length=Length(length=20, unit=LengthUnit.FEET),
|
|
current_a=20,
|
|
)
|
|
)
|
|
|
|
|
|
def max_wire_length(
|
|
gauge: int,
|
|
material: MaterialType,
|
|
current_amps: float,
|
|
voltage_drop: float = 0.3,
|
|
temperature: Temperature = Temperature(100.0, unit=TemperatureUnit.FAHRENHEIT),
|
|
) -> Length:
|
|
"""Calculate the maximum allowable wire length based on voltage drop criteria.
|
|
|
|
Args:
|
|
gauge (int): The AWG (American Wire Gauge) number of the wire
|
|
material (MaterialType): The type of conductor material (e.g., copper, aluminum)
|
|
current_amps (float): The current flowing through the wire in amperes
|
|
voltage_drop (float, optional): Maximum allowable voltage drop as a decimal (default 0.1 or 10%)
|
|
|
|
Returns:
|
|
float: Maximum wire length in meters that maintains the specified voltage drop
|
|
"""
|
|
resistivity = get_material_resistivity(material, temperature)
|
|
resistance_per_meter = resistivity / calculate_wire_area_m2(gauge)
|
|
# V = IR, solve for length where V is the allowed voltage drop
|
|
return Length(
|
|
voltage_drop / (current_amps * resistance_per_meter),
|
|
LengthUnit.METERS,
|
|
)
|
|
|
|
|
|
print(max_wire_length(gauge=10, material=MaterialType.CCA, current_amps=20).feet())
|
|
print(max_wire_length(gauge=10, material=MaterialType.CCA, current_amps=10).feet())
|
|
print(max_wire_length(gauge=10, material=MaterialType.CCA, current_amps=5).feet())
|