File size: 7,160 Bytes
b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd f78204f 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb 888a9bd b060cbb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
import gradio as gr
import math
import itertools
import ezdxf
import os
import groq
from ezdxf import zoom
from ezdxf.enums import TextEntityAlignment
# Initialize Groq client
client = groq.Client(api_key=os.getenv("GROQ_API_KEY"))
# Available Capacitor Units (kVAR)
available_capacitors = [25, 20, 15, 10, 5, 2.5, 1.5, 1]
# Prompt Groq for explanation (optional)
def ask_groq(prompt):
try:
response = client.chat.completions.create(
model="llama3-8b-8192",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
except Exception as e:
return f"Groq Error: {str(e)}"
def calculate_power_parameters(voltage, current, power_factor):
if voltage > 0 and current > 0:
apparent_power = math.sqrt(3) * voltage * current
real_power = apparent_power * power_factor / 1000
try:
reactive_power = math.sqrt((apparent_power / 1000) ** 2 - real_power ** 2)
except ValueError:
reactive_power = 0.0
calculated_pf = real_power * 1000 / apparent_power if apparent_power > 0 else 0
return {
"apparent_power": round(apparent_power, 2),
"real_power": round(real_power, 2),
"reactive_power": round(reactive_power, 2),
"calculated_pf": round(calculated_pf, 2)
}
else:
return None
def design_capacitor_bank(reactive_power, num_caps):
if reactive_power > 0 and num_caps > 0:
best_combo = None
min_error = float('inf')
# Allow repetition freely to match reactive power
combos = itertools.combinations_with_replacement(available_capacitors, num_caps)
for combo in combos:
total = sum(combo)
error = abs(total - reactive_power)
if error < min_error:
min_error = error
best_combo = combo
if error == 0:
break
if best_combo:
suggested_capacitors = [f"{cap} kVAR" for cap in best_combo]
total_kvar = sum(best_combo)
message = f"Total Compensation: {round(total_kvar, 2)} kVAR"
return {
"suggested_capacitors": suggested_capacitors,
"total_kvar": round(total_kvar, 2),
"message": message,
"combo": best_combo
}
else:
return {"message": "Could not find a suitable combination."}
else:
return None
def create_dxf_capacitor_bank(capacitors):
doc = ezdxf.new()
msp = doc.modelspace()
x = 0
y = 0
row_width = 15 # Distance between capacitors in a row
row_height = 20
max_in_row = 5
for idx, cap in enumerate(capacitors):
label = f"{cap} kVAR"
# Draw rectangle for capacitor
points = [(x, y), (x + 10, y), (x + 10, y + 10), (x, y + 10), (x, y)]
msp.add_lwpolyline(points, close=True, dxfattribs={'color': 3}) # Color 3 = Green
# Add Text with more control
text = msp.add_text(label, dxfattribs={
'height': 2.5,
'color': 4, # color Cyan
'style': 'STANDARD', # You can define text styles in DXF
'halign': TextEntityAlignment.CENTER, # Horizontal alignment
'valign': TextEntityAlignment.BOTTOM if hasattr(TextEntityAlignment, 'BOTTOM') else 2,
})
text.dxf.insert = (x + 5, y + 5) # Position at center of rectangle
x += row_width
if (idx + 1) % max_in_row == 0: # Move to the next row
x = 0
y += row_height
# Add a title
title_text = msp.add_text("Capacitor Bank Layout", dxfattribs={'height': 5, 'color': 1})
title_text.dxf.insert = (0, y + 30)
# Zoom to extents
zoom.extents(msp, factor=1.1) # Add a small padding
output_path = "capacitor_bank_layout.dxf"
doc.saveas(output_path)
return output_path
def reactive_power_first(voltage, current, power_factor):
power_results = calculate_power_parameters(voltage, current, power_factor)
if power_results:
apparent_power_out = f"Apparent Power: **{power_results['apparent_power']} VA**"
real_power_out = f"Real Power: **{power_results['real_power']} kW**"
reactive_power_out = f"Reactive Power: **{power_results['reactive_power']} kVAR**"
calculated_pf_out = f"Calculated Power Factor: **{power_results['calculated_pf']}**"
return (
apparent_power_out,
real_power_out,
reactive_power_out,
calculated_pf_out,
power_results['reactive_power']
)
else:
return ("⚠️ Please enter valid Voltage and Current!", "", "", "", 0)
def finalize_capacitor_bank(reactive_power, num_caps):
cap_bank_design = design_capacitor_bank(reactive_power, num_caps)
if cap_bank_design and cap_bank_design.get("suggested_capacitors"):
suggested_capacitors_text = "<br>".join(
[f"🔹 Capacitor {idx + 1}: **{cap}**" for idx, cap in enumerate(cap_bank_design['suggested_capacitors'])]
)
dxf_path = create_dxf_capacitor_bank(cap_bank_design["combo"])
return suggested_capacitors_text, cap_bank_design['message'], dxf_path
else:
return "Could not find a suitable combination.", "", None
with gr.Blocks() as iface:
gr.Markdown("# ⚡ Three-Phase Power Calculator - Reactive Power Compensation")
gr.Markdown("""
Step 1: Enter system parameters to calculate apparent and reactive power.<br>
Step 2: Input number of capacitors to compute optimal configuration.<br>
Step 3: Download AutoCAD (.dxf) layout.
""")
with gr.Row():
voltage = gr.Number(label="Enter Voltage (V)", value=415)
current = gr.Number(label="Enter Current (A)", value=250)
power_factor = gr.Slider(label="Power Factor", minimum=0.0, maximum=1.0, value=0.85, step=0.01)
frequency = gr.Radio(label="Select Frequency", choices=[50, 60], value=50)
calc_btn = gr.Button("🔍 Calculate Power Parameters")
apparent_power_out = gr.HTML()
real_power_out = gr.HTML()
reactive_power_out = gr.HTML()
calculated_pf_out = gr.HTML()
reactive_value = gr.Number(visible=False)
calc_btn.click(
fn=reactive_power_first,
inputs=[voltage, current, power_factor],
outputs=[
apparent_power_out,
real_power_out,
reactive_power_out,
calculated_pf_out,
reactive_value
]
)
gr.Markdown("### ➕ Enter number of capacitors to compensate reactive power:")
num_caps_input = gr.Number(label="Number of Capacitors", precision=0)
finalize_btn = gr.Button("⚙️ Generate Capacitor Bank")
capacitor_out = gr.HTML()
total_comp_out = gr.HTML()
dxf_file = gr.File(label="📥 Download AutoCAD File")
finalize_btn.click(
fn=finalize_capacitor_bank,
inputs=[reactive_value, num_caps_input],
outputs=[capacitor_out, total_comp_out, dxf_file]
)
if __name__ == "__main__":
iface.launch()
|