MuhammadSajid's picture
Update app.py
888a9bd verified
Raw History Blame Contribute Delete
7.16 kB
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()