Spaces:
Sleeping
Sleeping
| # HVAC Blueprint Analyzer - Output Generator & GUI Guide | |
| **Date**: June 19, 2026 | |
| **Component**: Output Generation & User Interface | |
| --- | |
| ## π OUTPUT GENERATOR OVERVIEW | |
| ### Purpose | |
| Convert analyzed HVAC data into multiple formats: | |
| - CSV files for spreadsheet analysis | |
| - PDF reports with visual summaries | |
| - JSON for API consumption | |
| - HTML reports for web viewing | |
| - Excel workbooks with multiple sheets | |
| --- | |
| ## π― PHASE A: CSV OUTPUT GENERATION | |
| ### CSV Output 1: Floor & Units Summary | |
| **File**: `hvac_analysis_floors_units.csv` | |
| ```csv | |
| Floor,Unit_ID,Unit_Type,Quantity,Capacity_BTU,Capacity_kW,Status,Notes | |
| 1,AC-A,Ceiling Concealed Ducted,1,36000,10.5,Detected,Located near kitchen | |
| 1,AC-B,Wall Mounted,1,24000,7.0,Detected,Bedroom unit | |
| 2,AC-C,Ceiling Concealed Ducted,1,36000,10.5,Detected,Master bedroom | |
| 2,AC-D,Wall Mounted,2,12000,3.5,Detected,Living areas | |
| 3,AC-E,Ceiling Concealed Ducted,1,48000,14.0,Detected,Commercial zone | |
| 3,AC-F,Wall Mounted,1,24000,7.0,Detected,Office area | |
| ``` | |
| **Columns to Include:** | |
| - [ ] Floor number (1, 2, 3, B for basement) | |
| - [ ] Unit ID/Tag (AC-A, AC-B, etc.) | |
| - [ ] Unit Type (Ceiling Concealed Ducted, Wall Mounted, Ductless, etc.) | |
| - [ ] Quantity (number of units) | |
| - [ ] Capacity in BTU | |
| - [ ] Capacity in kW | |
| - [ ] Detection Status (Detected, Manual Entry, Inferred) | |
| - [ ] Notes/Comments | |
| - [ ] Location within floor (optional) | |
| - [ ] Equipment Schedule reference (optional) | |
| **Implementation**: | |
| ```python | |
| def export_floors_units_csv(analysis_data, output_path): | |
| """ | |
| Export floor-by-floor unit breakdown to CSV | |
| Args: | |
| analysis_data: Dict with floors and units | |
| output_path: Path to save CSV | |
| Returns: | |
| Path to saved CSV file | |
| """ | |
| import pandas as pd | |
| rows = [] | |
| for floor in analysis_data['floors']: | |
| floor_num = floor['number'] | |
| for unit in floor['units']: | |
| rows.append({ | |
| 'Floor': floor_num, | |
| 'Unit_ID': unit['tag'], | |
| 'Unit_Type': unit['type'], | |
| 'Quantity': unit['quantity'], | |
| 'Capacity_BTU': unit.get('capacity_btu', ''), | |
| 'Capacity_kW': unit.get('capacity_kw', ''), | |
| 'Status': unit.get('detection_status', 'Detected'), | |
| 'Notes': unit.get('notes', ''), | |
| 'Location': unit.get('location', ''), | |
| }) | |
| df = pd.DataFrame(rows) | |
| df.to_csv(output_path, index=False) | |
| return output_path | |
| ``` | |
| ### CSV Output 2: Equipment Schedule | |
| **File**: `hvac_equipment_schedule.csv` | |
| ```csv | |
| Equipment_ID,Manufacturer,Model,Type,Capacity_BTU,Voltage,Phase,Frequency_Hz,Quantity,Floor,Unit_Tag,Remarks | |
| 1,Carrier,25HNE024A03,Ceiling Cassette,24000,208-230,1,60,1,2,AC-B,Installed Jan 2023 | |
| 2,Daikin,FCAG71B,Ceiling Concealed,36000,208-230,3,60,2,1,AC-A,New equipment | |
| 3,LG,ASNQ48LNZA0,Wall Mounted,48000,208-230,1,60,1,3,AC-E,High efficiency model | |
| ``` | |
| **Columns to Include:** | |
| - [ ] Equipment ID (from schedule) | |
| - [ ] Manufacturer | |
| - [ ] Model number | |
| - [ ] Equipment Type | |
| - [ ] Capacity (BTU) | |
| - [ ] Voltage | |
| - [ ] Phase (1 or 3) | |
| - [ ] Frequency (Hz) | |
| - [ ] Quantity | |
| - [ ] Floor number | |
| - [ ] Associated Unit Tag (AC-A, AC-B, etc.) | |
| - [ ] Remarks/Notes | |
| ### CSV Output 3: Reconciliation Report | |
| **File**: `hvac_reconciliation_report.csv` | |
| ```csv | |
| Issue_Type,Severity,Floor,Unit_ID,Detected_in_Plan,Found_in_Schedule,Details,Recommended_Action | |
| Missing_Unit,High,2,AC-B,No,Yes,Unit found in schedule but not detected in floor plan,Review floor plan markup | |
| Extra_Unit,Medium,1,AC-A,Yes,No,Unit detected in plan but not listed in schedule,Add to equipment schedule | |
| Capacity_Mismatch,Medium,3,AC-E,36000,48000,Plan shows 36kBTU but schedule lists 48kBTU,Verify actual installed capacity | |
| Floor_Mismatch,High,NULL,AC-C,3,2,Unit AC-C listed on floor 2 but appears in floor 3 plan,Correct schedule or floor plan | |
| ``` | |
| **Columns to Include:** | |
| - [ ] Issue Type (Missing Unit, Extra Unit, Capacity Mismatch, Floor Mismatch, etc.) | |
| - [ ] Severity (Low, Medium, High) | |
| - [ ] Floor number | |
| - [ ] Unit ID | |
| - [ ] Detected in floor plan (Yes/No) | |
| - [ ] Found in schedule (Yes/No) | |
| - [ ] Details/Description | |
| - [ ] Recommended Action | |
| - [ ] Confidence Score (0-100%) | |
| --- | |
| ## π₯οΈ PHASE B: GUI - USER INTERFACE | |
| ### Technology Stack (Recommended) | |
| - [ ] **Frontend Framework**: Streamlit (easiest for quick demo) OR React | |
| - [ ] **Styling**: Tailwind CSS (if React) OR Streamlit theme | |
| - [ ] **Charting**: Plotly or Chart.js (for visualizations) | |
| - [ ] **Forms**: Built-in Streamlit components OR React Hook Form | |
| ### GUI Features Checklist | |
| #### 1. **File Upload Section** | |
| ```python | |
| # Streamlit example | |
| import streamlit as st | |
| st.title("π’ HVAC Blueprint Analyzer") | |
| uploaded_file = st.file_uploader("Upload Mechanical Blueprint (PDF)", type="pdf") | |
| if uploaded_file: | |
| st.info(f"π File: {uploaded_file.name} ({uploaded_file.size / 1024:.2f} KB)") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| model_choice = st.radio("Choose AI Model:", ["Gemini", "OpenAI"]) | |
| with col2: | |
| schedule_mode = st.radio("Schedule Mode:", | |
| ["Auto-Detect", "Upload Schedule"]) | |
| if st.button("π Analyze Blueprint"): | |
| with st.spinner("Analyzing..."): | |
| results = analyze_blueprint(uploaded_file, model_choice, schedule_mode) | |
| st.success("Analysis complete!") | |
| ``` | |
| **Checklist:** | |
| - [ ] PDF upload widget | |
| - [ ] File validation (size, format) | |
| - [ ] Progress indicator during upload | |
| - [ ] File preview/info display | |
| - [ ] Multiple file upload support (batch processing) | |
| - [ ] Drag-and-drop file upload | |
| #### 2. **Configuration Section** | |
| - [ ] Model selection (Gemini vs OpenAI toggle) | |
| - [ ] Schedule mode selection (Auto vs Manual) | |
| - [ ] Output format selection (CSV, PDF, JSON) | |
| - [ ] Advanced options (OCR threshold, confidence limits) | |
| - [ ] Cost calculator (estimate before processing) | |
| #### 3. **Analysis Results Display** | |
| **Tab 1: Floors & Units Summary** | |
| ```python | |
| st.header("π Analysis Results") | |
| tab1, tab2, tab3, tab4 = st.tabs([ | |
| "Floors & Units", | |
| "Equipment Schedule", | |
| "Reconciliation", | |
| "Downloads" | |
| ]) | |
| with tab1: | |
| st.subheader("HVAC Units by Floor") | |
| # Interactive table | |
| st.dataframe( | |
| floors_units_df, | |
| use_container_width=True, | |
| column_config={ | |
| "Floor": st.column_config.TextColumn("Floor"), | |
| "Unit_ID": st.column_config.TextColumn("Unit ID", width="medium"), | |
| "Unit_Type": st.column_config.TextColumn("Type", width="medium"), | |
| "Quantity": st.column_config.NumberColumn("Qty"), | |
| "Capacity_BTU": st.column_config.NumberColumn("BTU"), | |
| } | |
| ) | |
| # Summary statistics | |
| col1, col2, col3, col4 = st.columns(4) | |
| with col1: | |
| st.metric("Total Floors", len(analysis_data['floors'])) | |
| with col2: | |
| st.metric("Total Units", sum([u['quantity'] for f in analysis_data['floors'] for u in f['units']])) | |
| with col3: | |
| st.metric("Total Capacity", f"{total_btu:,.0f} BTU") | |
| with col4: | |
| st.metric("Cost (Gemini)", f"${cost:.2f}") | |
| ``` | |
| **Tab 2: Equipment Schedule Table** | |
| - [ ] Sortable table with equipment details | |
| - [ ] Filter by floor, manufacturer, type | |
| - [ ] Search functionality | |
| - [ ] Edit capability (for manual corrections) | |
| - [ ] Export to CSV | |
| **Tab 3: Reconciliation Report** | |
| - [ ] Visual summary of issues (count by severity) | |
| - [ ] Detailed issue list | |
| - [ ] Severity indicators (color-coded) | |
| - [ ] Recommended actions | |
| - [ ] Mark issues as resolved | |
| **Tab 4: Downloads** | |
| - [ ] Download CSV files (Floors & Units, Schedule, Reconciliation) | |
| - [ ] Download PDF report | |
| - [ ] Download JSON data | |
| - [ ] Zip all outputs together | |
| #### 4. **Visualization Components** | |
| **Floor Plan Overview** | |
| ```python | |
| import plotly.graph_objects as go | |
| fig = go.Figure() | |
| # Add floor layers | |
| for floor in analysis_data['floors']: | |
| fig.add_trace(go.Scatter( | |
| x=floor['units_x'], | |
| y=floor['units_y'], | |
| mode='markers+text', | |
| text=floor['units_tags'], | |
| marker=dict(size=15, color='blue'), | |
| name=f"Floor {floor['number']}" | |
| )) | |
| st.plotly_chart(fig, use_container_width=True) | |
| ``` | |
| **Capacity Distribution Chart** | |
| - [ ] Stacked bar chart showing capacity by floor | |
| - [ ] Unit type distribution pie chart | |
| - [ ] Comparison chart (Detected vs Schedule) | |
| **Cost Breakdown** | |
| - [ ] API cost per model comparison | |
| - [ ] Cost per unit analyzed | |
| - [ ] Total project cost estimate | |
| #### 5. **Schedule Upload Section** (if auto-detect fails) | |
| ```python | |
| with st.expander("π Manual Schedule Upload"): | |
| schedule_source = st.radio( | |
| "How would you like to provide the schedule?", | |
| ["Upload CSV", "Upload Excel", "Paste Data", "Use Previous Schedule"] | |
| ) | |
| if schedule_source == "Upload CSV": | |
| schedule_file = st.file_uploader("Upload CSV with schedule", type="csv") | |
| if schedule_file: | |
| schedule_df = pd.read_csv(schedule_file) | |
| st.dataframe(schedule_df) | |
| elif schedule_source == "Paste Data": | |
| schedule_text = st.text_area("Paste schedule data (CSV format)") | |
| if schedule_text: | |
| schedule_df = pd.read_csv(StringIO(schedule_text)) | |
| st.dataframe(schedule_df) | |
| ``` | |
| **Checklist:** | |
| - [ ] CSV upload | |
| - [ ] Excel upload (.xlsx, .xls) | |
| - [ ] Copy/paste data | |
| - [ ] Data validation | |
| - [ ] Preview of uploaded data | |
| - [ ] Confirm & save schedule | |
| #### 6. **A/B Testing Comparison View** | |
| ```python | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.subheader("π΅ Gemini Results") | |
| st.write(f"Time: {gemini_time:.2f}s") | |
| st.write(f"Cost: ${gemini_cost:.4f}") | |
| st.write(f"Units Found: {gemini_units}") | |
| st.dataframe(gemini_results) | |
| with col2: | |
| st.subheader("π OpenAI Results") | |
| st.write(f"Time: {openai_time:.2f}s") | |
| st.write(f"Cost: ${openai_cost:.4f}") | |
| st.write(f"Units Found: {openai_units}") | |
| st.dataframe(openai_results) | |
| # Comparison metrics | |
| st.subheader("π Comparison") | |
| comparison_data = { | |
| 'Metric': ['Speed (seconds)', 'Cost ($)', 'Units Detected', 'Accuracy (%)'], | |
| 'Gemini': [gemini_time, gemini_cost, gemini_units, gemini_accuracy], | |
| 'OpenAI': [openai_time, openai_cost, openai_units, openai_accuracy] | |
| } | |
| comparison_df = pd.DataFrame(comparison_data) | |
| st.dataframe(comparison_df, use_container_width=True) | |
| ``` | |
| --- | |
| ## π PHASE C: PDF REPORT GENERATION | |
| ### Report Sections | |
| - [ ] **Cover Page** | |
| - [ ] Project name | |
| - [ ] Analysis date | |
| - [ ] Number of blueprints analyzed | |
| - [ ] Model used (Gemini/OpenAI) | |
| - [ ] **Executive Summary** | |
| - [ ] Total units found | |
| - [ ] Total capacity | |
| - [ ] Number of floors | |
| - [ ] Key findings | |
| - [ ] **Floor-by-Floor Summary** | |
| - [ ] Table of units per floor | |
| - [ ] Visual breakdown | |
| - [ ] **Equipment Schedule** | |
| - [ ] Full equipment table | |
| - [ ] Specifications | |
| - [ ] **Reconciliation Issues** | |
| - [ ] List of discrepancies | |
| - [ ] Severity indicators | |
| - [ ] Recommended actions | |
| - [ ] **Appendix** | |
| - [ ] Analysis parameters | |
| - [ ] Processing time | |
| - [ ] Cost breakdown | |
| ### PDF Generation Library | |
| ```python | |
| from reportlab.lib.pagesizes import letter, A4 | |
| from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph | |
| import pandas as pd | |
| def generate_pdf_report(analysis_data, output_path): | |
| """Generate comprehensive PDF report""" | |
| from reportlab.lib import colors | |
| from reportlab.lib.units import inch | |
| doc = SimpleDocTemplate(output_path, pagesize=letter) | |
| elements = [] | |
| # Title | |
| title = Paragraph( | |
| "<font size=24><b>HVAC Blueprint Analysis Report</b></font>", | |
| style=ParagraphStyle(alignment=1) # Center aligned | |
| ) | |
| elements.append(title) | |
| elements.append(Spacer(1, 0.5*inch)) | |
| # Summary table | |
| summary_data = [ | |
| ['Total Floors', str(len(analysis_data['floors']))], | |
| ['Total Units', str(sum_units(analysis_data))], | |
| ['Total Capacity', f"{total_btu(analysis_data):,} BTU"], | |
| ] | |
| summary_table = Table(summary_data) | |
| summary_table.setStyle(TableStyle([ | |
| ('BACKGROUND', (0, 0), (-1, 0), colors.grey), | |
| ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), | |
| ('ALIGN', (0, 0), (-1, -1), 'CENTER'), | |
| ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), | |
| ('FONTSIZE', (0, 0), (-1, 0), 14), | |
| ('BOTTOMPADDING', (0, 0), (-1, 0), 12), | |
| ('GRID', (0, 0), (-1, -1), 1, colors.black) | |
| ])) | |
| elements.append(summary_table) | |
| # Build PDF | |
| doc.build(elements) | |
| return output_path | |
| ``` | |
| **Checklist:** | |
| - [ ] ReportLab setup | |
| - [ ] Cover page generation | |
| - [ ] Table formatting | |
| - [ ] Chart embedding | |
| - [ ] Multi-page support | |
| - [ ] Table of contents | |
| - [ ] Page numbering | |
| --- | |
| ## π PHASE D: JSON OUTPUT | |
| ### JSON Structure | |
| ```json | |
| { | |
| "metadata": { | |
| "analysis_date": "2026-06-19T10:30:00Z", | |
| "blueprint_file": "353_E_86th_St.pdf", | |
| "model_used": "gemini-2.5-pro", | |
| "processing_time_seconds": 25.3, | |
| "cost_usd": 0.08 | |
| }, | |
| "summary": { | |
| "total_floors": 3, | |
| "total_units": 8, | |
| "total_capacity_btu": 256000, | |
| "total_capacity_kw": 75.0 | |
| }, | |
| "floors": [ | |
| { | |
| "floor_number": 1, | |
| "floor_type": "residential", | |
| "units": [ | |
| { | |
| "id": "AC-A", | |
| "type": "Ceiling Concealed Ducted", | |
| "quantity": 1, | |
| "capacity_btu": 36000, | |
| "capacity_kw": 10.5, | |
| "manufacturer": "Carrier", | |
| "model": "25HNE024A03", | |
| "location": "Living area", | |
| "detection_confidence": 0.95 | |
| } | |
| ] | |
| } | |
| ], | |
| "equipment_schedule": [ | |
| { | |
| "id": 1, | |
| "manufacturer": "Carrier", | |
| "model": "25HNE024A03", | |
| "type": "Ceiling Cassette", | |
| "capacity_btu": 24000, | |
| "voltage": "208-230V", | |
| "phase": 1, | |
| "frequency_hz": 60, | |
| "quantity": 1, | |
| "floor": 2, | |
| "unit_tag": "AC-B" | |
| } | |
| ], | |
| "reconciliation": { | |
| "issues_found": 2, | |
| "high_severity": 0, | |
| "medium_severity": 2, | |
| "low_severity": 0, | |
| "issues": [ | |
| { | |
| "type": "capacity_mismatch", | |
| "floor": 3, | |
| "unit_id": "AC-E", | |
| "plan_capacity": 36000, | |
| "schedule_capacity": 48000, | |
| "severity": "medium", | |
| "recommendation": "Verify actual installed capacity" | |
| } | |
| ] | |
| } | |
| } | |
| ``` | |
| **Checklist:** | |
| - [ ] Metadata section | |
| - [ ] Summary statistics | |
| - [ ] Detailed floor data | |
| - [ ] Equipment schedule | |
| - [ ] Reconciliation issues | |
| - [ ] Confidence scores | |
| - [ ] Timestamps | |
| --- | |
| ## π₯οΈ PHASE E: GUI IMPLEMENTATION OPTIONS | |
| ### Option 1: Streamlit (Recommended for Quick Demo) | |
| **Pros:** | |
| - Fastest to build | |
| - No frontend experience needed | |
| - Built-in data visualization | |
| - Free hosting on Streamlit Cloud | |
| **Cons:** | |
| - Limited customization | |
| - Not suitable for production UIs | |
| - Slower for large datasets | |
| **Setup:** | |
| ```bash | |
| pip install streamlit plotly pandas openpyxl | |
| streamlit run app.py | |
| ``` | |
| ### Option 2: React + FastAPI | |
| **Pros:** | |
| - Full customization | |
| - Production-quality UI | |
| - Better performance | |
| - Responsive design | |
| **Cons:** | |
| - Takes longer to build | |
| - Requires frontend/backend skills | |
| - More complex deployment | |
| **Setup:** | |
| ```bash | |
| # Backend | |
| pip install fastapi uvicorn pydantic | |
| # Frontend | |
| npm create vite@latest hvac-ui -- --template react | |
| npm install axios react-query | |
| ``` | |
| ### Option 3: Simple HTML + jQuery | |
| **Pros:** | |
| - Minimal dependencies | |
| - Fast to build | |
| - Easy to deploy | |
| - No build step needed | |
| **Cons:** | |
| - Limited functionality | |
| - Not modern | |
| - Harder to maintain | |
| --- | |
| ## π CSV EXPORT IMPLEMENTATION CHECKLIST | |
| ### Code Structure | |
| ```python | |
| # outputs/csv_exporter.py | |
| import pandas as pd | |
| from typing import Dict, List | |
| from pathlib import Path | |
| class HVACCSVExporter: | |
| """Export HVAC analysis data to CSV formats""" | |
| def __init__(self, output_dir: str = "./outputs"): | |
| self.output_dir = Path(output_dir) | |
| self.output_dir.mkdir(exist_ok=True) | |
| def export_all(self, analysis_data: Dict) -> Dict[str, Path]: | |
| """Export all CSV files and return paths""" | |
| return { | |
| 'floors_units': self.export_floors_units(analysis_data), | |
| 'equipment_schedule': self.export_equipment_schedule(analysis_data), | |
| 'reconciliation': self.export_reconciliation(analysis_data), | |
| 'summary': self.export_summary(analysis_data), | |
| } | |
| def export_floors_units(self, data: Dict) -> Path: | |
| """Export floor and unit breakdown""" | |
| rows = [] | |
| for floor in data['floors']: | |
| for unit in floor['units']: | |
| rows.append({ | |
| 'Floor': floor['number'], | |
| 'Unit_ID': unit['tag'], | |
| 'Unit_Type': unit['type'], | |
| 'Quantity': unit['quantity'], | |
| 'Capacity_BTU': unit.get('capacity_btu'), | |
| 'Capacity_kW': unit.get('capacity_kw'), | |
| 'Status': unit.get('detection_status', 'Detected'), | |
| 'Location': unit.get('location', ''), | |
| 'Notes': unit.get('notes', ''), | |
| }) | |
| df = pd.DataFrame(rows) | |
| path = self.output_dir / "hvac_floors_units.csv" | |
| df.to_csv(path, index=False) | |
| return path | |
| def export_equipment_schedule(self, data: Dict) -> Path: | |
| """Export equipment schedule""" | |
| df = pd.DataFrame(data.get('equipment_schedule', [])) | |
| path = self.output_dir / "hvac_equipment_schedule.csv" | |
| df.to_csv(path, index=False) | |
| return path | |
| def export_reconciliation(self, data: Dict) -> Path: | |
| """Export reconciliation report""" | |
| issues = data.get('reconciliation', {}).get('issues', []) | |
| df = pd.DataFrame(issues) | |
| path = self.output_dir / "hvac_reconciliation.csv" | |
| df.to_csv(path, index=False) | |
| return path | |
| def export_summary(self, data: Dict) -> Path: | |
| """Export summary statistics""" | |
| summary = data.get('summary', {}) | |
| summary_df = pd.DataFrame([summary]) | |
| path = self.output_dir / "hvac_summary.csv" | |
| summary_df.to_csv(path, index=False) | |
| return path | |
| # Usage | |
| exporter = HVACCSVExporter() | |
| csv_files = exporter.export_all(analysis_data) | |
| print(f"Exported to: {csv_files}") | |
| ``` | |
| **Checklist:** | |
| - [ ] CSV exporter class created | |
| - [ ] floors_units.csv export working | |
| - [ ] equipment_schedule.csv export working | |
| - [ ] reconciliation.csv export working | |
| - [ ] summary.csv export working | |
| - [ ] Error handling for missing data | |
| - [ ] File encoding (UTF-8) | |
| - [ ] Column ordering consistent | |
| --- | |
| ## π¨ GUI MOCKUP LAYOUT | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| β π’ HVAC Blueprint Analyzer β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β β | |
| β π€ Upload Blueprint β | |
| β βββββββββββββββββββββββββββββββββββββββββββ β | |
| β β Drag & drop PDF here or click to browse β β | |
| β βββββββββββββββββββββββββββββββββββββββββββ β | |
| β β | |
| β βοΈ Configuration β | |
| β Model: [Gemini β] [OpenAI β] β | |
| β Schedule: [Auto-Detect β] [Upload β] β | |
| β Output Format: [CSV β] [PDF β] [JSON β] β | |
| β β | |
| β [π Analyze Blueprint] [πΎ Save Config]β | |
| β β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββ€ | |
| β π Results (Tabs) β | |
| β [Floors & Units] [Equipment] [Reconciliation] [Downloads] β | |
| β β | |
| β ββ Floors & Units βββββββββββββββββββββββββββ β | |
| β β β β | |
| β β Summary Statistics: β β | |
| β β ββββββββββββ¬βββββββββββ¬βββββββββββ¬βββββββ β β | |
| β β β Floors β Units β Capacity β Cost β β β | |
| β β β 3 β 8 β256kBTU β$0.08 β β β | |
| β β ββββββββββββ΄βββββββββββ΄βββββββββββ΄βββββββ β β | |
| β β β β | |
| β β Detailed Table: β β | |
| β β ββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β βFloorβUnit IDβType βQtyβBTU ββ β | |
| β β βββββββββββββββββββββββββββββββββββββββββββ€β β | |
| β β β 1 β AC-A βCeiling Duct β 1 β36000 ββ β | |
| β β β 1 β AC-B βWall Mount β 1 β24000 ββ β | |
| β β β 2 β AC-C βCeiling Duct β 1 β36000 ββ β | |
| β β β 2 β AC-D βWall Mount β 2 β24000 ββ β | |
| β β ββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β β β | |
| β β [π Chart View] [π Table View] [π Refresh]β β | |
| β ββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β | |
| β ββ Downloads βββββββββββββββββββββββββββββββββ β | |
| β β β β | |
| β β Available Outputs: β β | |
| β β β Floors & Units (CSV) [β¬ Download] β β | |
| β β β Equipment Schedule (CSV) [β¬ Download] β β | |
| β β β Reconciliation (CSV) [β¬ Download] β β | |
| β β β Analysis Report (PDF) [β¬ Download] β β | |
| β β β β | |
| β β [π¦ Download All as ZIP] β β | |
| β ββββββββββββββββββββββββββββββββββββββββββββββ β | |
| β β | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ``` | |
| --- | |
| ## π IMPLEMENTATION ORDER | |
| ### Week 1: CSV Output & Basic GUI | |
| 1. [ ] Create CSV exporter (all 3 CSV types) | |
| 2. [ ] Test CSV output with sample data | |
| 3. [ ] Build basic Streamlit app with file upload | |
| 4. [ ] Add results display table | |
| ### Week 2: Full GUI & Visualizations | |
| 5. [ ] Add charts and visualizations | |
| 6. [ ] Implement tabs (Floors, Schedule, Reconciliation) | |
| 7. [ ] Add schedule upload functionality | |
| 8. [ ] Create downloads section | |
| ### Week 3: Polish & Deployment | |
| 9. [ ] PDF report generation | |
| 10. [ ] A/B testing comparison view | |
| 11. [ ] Error handling and validation | |
| 12. [ ] Deploy to Streamlit Cloud or cloud provider | |
| --- | |
| ## π SUCCESS CRITERIA | |
| **CSV Output:** | |
| - β All three CSVs generated successfully | |
| - β Data is accurate and complete | |
| - β Columns are properly labeled | |
| - β No missing values (or clearly marked) | |
| **GUI:** | |
| - β File upload works smoothly | |
| - β Results display in <2 seconds | |
| - β All tabs functional | |
| - β Download buttons work | |
| - β Mobile-responsive (if web) | |
| **Integration:** | |
| - β FastAPI endpoint returns CSVs | |
| - β GUI calls API correctly | |
| - β Error messages are clear | |
| - β No hardcoded paths | |
| --- | |
| ## π INTEGRATION WITH FASTAPI | |
| ```python | |
| # main.py - FastAPI app with CSV export | |
| from fastapi import FastAPI, UploadFile, File | |
| from fastapi.responses import FileResponse, StreamingResponse | |
| from outputs.csv_exporter import HVACCSVExporter | |
| import zipfile | |
| from io import BytesIO | |
| app = FastAPI() | |
| exporter = HVACCSVExporter() | |
| @app.post("/analyze") | |
| async def analyze_blueprint(file: UploadFile = File(...)): | |
| """Analyze blueprint and return results""" | |
| analysis_data = await process_blueprint(file) | |
| # Generate CSVs | |
| csv_files = exporter.export_all(analysis_data) | |
| return { | |
| "status": "success", | |
| "analysis": analysis_data, | |
| "csv_files": {name: str(path) for name, path in csv_files.items()} | |
| } | |
| @app.get("/download/csv/{csv_type}") | |
| async def download_csv(csv_type: str, task_id: str): | |
| """Download specific CSV file""" | |
| file_path = f"./outputs/{task_id}_{csv_type}.csv" | |
| return FileResponse(file_path, filename=f"hvac_{csv_type}.csv") | |
| @app.get("/download/all/{task_id}") | |
| async def download_all(task_id: str): | |
| """Download all outputs as ZIP""" | |
| zip_buffer = BytesIO() | |
| with zipfile.ZipFile(zip_buffer, 'w') as zf: | |
| zf.write(f"./outputs/{task_id}_floors_units.csv") | |
| zf.write(f"./outputs/{task_id}_equipment_schedule.csv") | |
| zf.write(f"./outputs/{task_id}_reconciliation.csv") | |
| zf.write(f"./outputs/{task_id}_report.pdf") | |
| zip_buffer.seek(0) | |
| return StreamingResponse( | |
| iter([zip_buffer.getvalue()]), | |
| media_type="application/zip", | |
| headers={"Content-Disposition": "attachment; filename=hvac_analysis.zip"} | |
| ) | |
| ``` | |
| **Checklist:** | |
| - [ ] /analyze endpoint returns CSV file paths | |
| - [ ] /download/csv/{type} serves files | |
| - [ ] /download/all/{task_id} creates ZIP | |
| - [ ] Content-Type headers correct | |
| - [ ] Filenames are descriptive | |
| - [ ] Error handling for missing files | |