Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import numpy as np | |
| from PIL import Image, ImageDraw, ImageFont | |
| def overlay_plan(image, sockets, switches, room_type, price_socket, price_switch, cable_per_point_m, cable_price_per_m, customer_view): | |
| img = image.convert("RGBA") | |
| w, h = img.size | |
| draw = ImageDraw.Draw(img) | |
| # simple suggested positions (rule-based) | |
| # sockets along lower wall line; switches near "door" area left side | |
| socket_points = [] | |
| switch_points = [] | |
| # distribute sockets on bottom area | |
| for i in range(sockets): | |
| x = int((i + 1) * w / (sockets + 1)) | |
| y = int(h * 0.83) | |
| socket_points.append((x, y)) | |
| # switches on left side mid height | |
| for i in range(switches): | |
| x = int(w * 0.12) | |
| y = int(h * (0.45 + (i - (switches-1)/2) * 0.12)) | |
| switch_points.append((x, y)) | |
| # draw overlays | |
| def draw_marker(xy, label, color): | |
| r = max(10, int(min(w, h) * 0.015)) | |
| x, y = xy | |
| draw.ellipse((x-r, y-r, x+r, y+r), outline=color, width=4) | |
| draw.text((x+r+6, y-r-6), label, fill=color) | |
| for idx, p in enumerate(socket_points, start=1): | |
| draw_marker(p, f"SD{idx}", (0, 255, 0, 255)) # Steckdose | |
| for idx, p in enumerate(switch_points, start=1): | |
| draw_marker(p, f"SW{idx}", (255, 165, 0, 255)) # Schalter | |
| # rough cable estimate | |
| points_total = sockets + switches | |
| cable_m = points_total * max(0.0, float(cable_per_point_m)) | |
| # costs | |
| cost_sockets = sockets * float(price_socket) | |
| cost_switches = switches * float(price_switch) | |
| cost_cable = cable_m * float(cable_price_per_m) | |
| total = cost_sockets + cost_switches + cost_cable | |
| if customer_view: | |
| summary = ( | |
| f"Raumtyp: {room_type}\n" | |
| f"Vorschlag: {sockets} Steckdosen, {switches} Schalter\n" | |
| f"Geschätzte Leitung: {cable_m:.1f} m\n" | |
| f"(Kosten ausgeblendet – Kundenansicht)" | |
| ) | |
| else: | |
| summary = ( | |
| f"Raumtyp: {room_type}\n" | |
| f"Steckdosen: {sockets} x {price_socket:.2f} € = {cost_sockets:.2f} €\n" | |
| f"Schalter: {switches} x {price_switch:.2f} € = {cost_switches:.2f} €\n" | |
| f"Leitung: {cable_m:.1f} m x {cable_price_per_m:.2f} € = {cost_cable:.2f} €\n" | |
| f"-----------------------------\n" | |
| f"Summe (grob): {total:.2f} €" | |
| ) | |
| return img.convert("RGB"), summary | |
| with gr.Blocks(title="Smartelektric – Raum-Planer (Prototyp)") as demo: | |
| gr.Markdown("## Smartelektric – Raum-Planer (Prototyp)\nFoto hochladen → Vorschlag + Material/Kosten grob") | |
| with gr.Row(): | |
| inp = gr.Image(type="pil", label="Raumfoto (Rohbau / Bestand)") | |
| out = gr.Image(type="pil", label="Vorschau mit Markierungen") | |
| room_type = gr.Dropdown( | |
| ["Wohnzimmer", "Schlafzimmer", "Küche", "Bad", "Flur", "Büro", "Kinderzimmer", "Sonstiges"], | |
| value="Wohnzimmer", | |
| label="Raumtyp" | |
| ) | |
| with gr.Row(): | |
| sockets = gr.Slider(0, 20, value=6, step=1, label="Anzahl Steckdosen (Vorschlag)") | |
| switches = gr.Slider(0, 10, value=2, step=1, label="Anzahl Schalter (Vorschlag)") | |
| with gr.Row(): | |
| price_socket = gr.Number(value=50, label="Preis pro Steckdose (inkl. z.B. 5m Leitung) €") | |
| price_switch = gr.Number(value=25, label="Preis pro Schalter €") | |
| with gr.Row(): | |
| cable_per_point_m = gr.Number(value=5, label="Leitung pro Punkt (m) – grobe Annahme") | |
| cable_price_per_m = gr.Number(value=1.8, label="Leitungspreis pro Meter €") | |
| customer_view = gr.Checkbox(value=False, label="Kundenansicht (Kosten ausblenden)") | |
| summary = gr.Textbox(label="Auswertung", lines=10) | |
| btn = gr.Button("Generieren") | |
| btn.click( | |
| overlay_plan, | |
| inputs=[inp, sockets, switches, room_type, price_socket, price_switch, cable_per_point_m, cable_price_per_m, customer_view], | |
| outputs=[out, summary] | |
| ) | |
| demo.launch() | |