Spaces:
Running
Running
import streamlit as st | |
import base64 | |
import requests | |
import json | |
st.set_page_config(page_title="Solar Rooftop Analyzer", layout="centered") | |
st.title("\U0001F31E Solar Rooftop Analysis") | |
st.markdown("Upload a rooftop image and provide your location and budget. The system will analyze the rooftop and estimate potential solar installation ROI.") | |
# Constants | |
OPENROUTER_API_KEY = "your_openrouter_api_key_here" | |
VISION_MODEL_NAME = "opengvlab/internvl3-14b:free" | |
# Helpers | |
def analyze_image_with_openrouter(image_bytes): | |
encoded_image = base64.b64encode(image_bytes).decode("utf-8") | |
prompt = ( | |
"Analyze the rooftop in this image. Output JSON with: [Roof area (sqm), " | |
"Sunlight availability (%), Shading (Yes/No), Recommended solar panel type, " | |
"Estimated capacity (kW)]." | |
) | |
headers = { | |
"Authorization": f"Bearer {OPENROUTER_API_KEY}", | |
"Content-Type": "application/json" | |
} | |
payload = { | |
"model": VISION_MODEL_NAME, | |
"messages": [ | |
{"role": "user", "content": [ | |
{"type": "text", "text": prompt}, | |
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{encoded_image}"}} | |
]} | |
] | |
} | |
response = requests.post("https://openrouter.ai/api/v1/chat/completions", json=payload, headers=headers) | |
if response.status_code == 200: | |
return response.json() | |
return {"error": "Failed to analyze image."} | |
def estimate_roi(roof_area, capacity_kw, budget): | |
cost_per_kw = 65000 # INR/kW | |
estimated_cost = capacity_kw * cost_per_kw | |
incentives = estimated_cost * 0.30 | |
net_cost = estimated_cost - incentives | |
annual_savings = capacity_kw * 1500 * 7 | |
payback_years = round(net_cost / annual_savings, 2) | |
return { | |
"estimated_cost": estimated_cost, | |
"incentives": incentives, | |
"net_cost": net_cost, | |
"annual_savings": annual_savings, | |
"payback_years": payback_years, | |
"within_budget": budget >= net_cost | |
} | |
# UI | |
with st.form("solar_form"): | |
image = st.file_uploader("Upload Rooftop Image", type=["jpg", "jpeg", "png"]) | |
location = st.text_input("Location") | |
budget = st.number_input("Budget (INR)", min_value=10000.0, step=1000.0) | |
submitted = st.form_submit_button("Analyze") | |
if submitted: | |
if image and location and budget: | |
with st.spinner("Analyzing rooftop image..."): | |
image_data = image.read() | |
ai_response = analyze_image_with_openrouter(image_data) | |
if "choices" in ai_response: | |
try: | |
content = ai_response["choices"][0]["message"]["content"] | |
content_json = json.loads(content) | |
st.success("Analysis complete!") | |
st.subheader("Rooftop Analysis") | |
st.json(content_json) | |
if "Roof area (sqm)" in content_json and "Estimated capacity (kW)" in content_json: | |
roi = estimate_roi( | |
roof_area=content_json["Roof area (sqm)"], | |
capacity_kw=content_json["Estimated capacity (kW)"], | |
budget=budget | |
) | |
st.subheader("ROI Estimation") | |
st.json(roi) | |
except Exception as e: | |
st.error(f"Error parsing analysis content: {e}") | |
st.json(ai_response) | |
else: | |
st.error("Failed to analyze the image. Please try again.") | |
else: | |
st.warning("Please upload an image and fill all fields.") |