Spaces:
Running
Running
File size: 4,635 Bytes
749787c 56ed549 d6091f9 7e5229d 610e7e5 749787c 56ed549 1e99778 56ed549 d6091f9 610e7e5 7e5229d d6091f9 7e5229d 56ed549 7e5229d 56ed549 7e5229d 56ed549 7e5229d 56ed549 610e7e5 d6091f9 610e7e5 56ed549 7e5229d 56ed549 7e5229d 56ed549 7e5229d d6091f9 56ed549 7e5229d 56ed549 d6091f9 56ed549 d6091f9 56ed549 d6091f9 56ed549 d6091f9 7e5229d 56ed549 7e5229d 56ed549 0259dad 7e5229d |
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 |
import streamlit as st
import base64
import requests
import json
import io
import re
from PIL import Image
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.")
OPENROUTER_API_KEY = "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"
VISION_MODEL_NAME = "opengvlab/internvl3-14b:free"
def analyze_image_with_openrouter(image_file):
# Read and convert image to JPEG bytes
img = Image.open(image_file).convert("RGB")
buffer = io.BytesIO()
img.save(buffer, format="JPEG")
jpeg_bytes = buffer.getvalue()
# Base64 encode with content-type prefix
encoded_image = "data:image/jpeg;base64," + base64.b64encode(jpeg_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": 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": f"Failed to analyze image. Status code: {response.status_code}, Response: {response.text}"}
def extract_json_from_response(content):
try:
match = re.search(r"\{.*\}", content, re.DOTALL)
if match:
return json.loads(match.group(0))
except Exception as e:
st.warning(f"Failed to parse JSON: {e}")
return None
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
}
with st.form("solar_form"):
uploaded_file = 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 uploaded_file and location and budget:
st.image(uploaded_file, caption="Uploaded Rooftop Image", use_column_width=True)
with st.spinner("Analyzing rooftop image..."):
ai_response = analyze_image_with_openrouter(uploaded_file)
if "choices" in ai_response:
try:
content = ai_response["choices"][0]["message"]["content"]
content_json = extract_json_from_response(content)
if content_json:
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)
else:
st.error("Could not extract structured data from the AI response.")
st.text(content) # Fallback: show raw content
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.")
|