""" Export utilities for HVAC Load Calculator This module provides functions for exporting data from the HVAC Load Calculator. """ import json import csv import io import pandas as pd from datetime import datetime def export_data(form_data, results, format='json'): """ Export form data and calculation results. Args: form_data (dict): Form input data results (dict): Calculation results format (str): Export format ('json' or 'csv') Returns: str: Exported data as string """ if format == 'json': return export_as_json(form_data, results) elif format == 'csv': return export_as_csv(form_data, results) else: raise ValueError(f"Unsupported export format: {format}") def export_as_json(form_data, results): """ Export data as JSON. Args: form_data (dict): Form input data results (dict): Calculation results Returns: str: JSON string """ # Combine form data and results export_data = { 'form_data': form_data, 'results': results, 'export_timestamp': datetime.now().isoformat() } # Convert to JSON string return json.dumps(export_data, indent=2) def export_as_csv(form_data, results): """ Export data as CSV. Args: form_data (dict): Form input data results (dict): Calculation results Returns: str: CSV string """ # Create a buffer for CSV data output = io.StringIO() writer = csv.writer(output) # Write header writer.writerow(['HVAC Load Calculator Results', datetime.now().isoformat()]) writer.writerow([]) # Write building information writer.writerow(['Building Information']) building_info = form_data.get('building_info', {}) for key, value in building_info.items(): writer.writerow([key, value]) writer.writerow([]) # Write calculation results writer.writerow(['Calculation Results']) for key, value in results.items(): if key not in ['building_info', 'timestamp'] and not isinstance(value, dict): writer.writerow([key, value]) writer.writerow([]) # Write load components writer.writerow(['Load Components']) writer.writerow(['Component', 'Load (W)', 'Percentage (%)']) # Calculate percentages sensible_load = results.get('sensible_load', 1) # Avoid division by zero components = { 'Conduction (Opaque Surfaces)': results.get('conduction_gain', 0), 'Conduction (Windows)': results.get('window_conduction_gain', 0), 'Solar Radiation (Windows)': results.get('window_solar_gain', 0), 'Infiltration & Ventilation': results.get('infiltration_gain', 0), 'Internal Gains': results.get('internal_gain', 0) } for component, load in components.items(): percentage = (load / sensible_load) * 100 if sensible_load > 0 else 0 writer.writerow([component, f"{load:.2f}", f"{percentage:.2f}"]) # Get CSV content return output.getvalue() def generate_report(form_data, results, calculation_type='cooling'): """ Generate a formatted report of calculation results. Args: form_data (dict): Form input data results (dict): Calculation results calculation_type (str): Type of calculation ('cooling' or 'heating') Returns: str: Formatted report as HTML """ # Create a DataFrame for the report report_data = [] # Add building information building_info = form_data.get('building_info', {}) report_data.append({ 'Section': 'Building Information', 'Item': 'Building Name', 'Value': building_info.get('building_name', 'N/A') }) report_data.append({ 'Section': 'Building Information', 'Item': 'Location', 'Value': building_info.get('location_name', 'N/A') }) report_data.append({ 'Section': 'Building Information', 'Item': 'Floor Area', 'Value': f"{building_info.get('floor_area', 0):.2f} m²" }) report_data.append({ 'Section': 'Building Information', 'Item': 'Volume', 'Value': f"{building_info.get('volume', 0):.2f} m³" }) # Add calculation results if calculation_type == 'cooling': report_data.append({ 'Section': 'Results', 'Item': 'Sensible Cooling Load', 'Value': f"{results.get('sensible_load', 0):.2f} W" }) report_data.append({ 'Section': 'Results', 'Item': 'Latent Cooling Load', 'Value': f"{results.get('latent_load', 0):.2f} W" }) report_data.append({ 'Section': 'Results', 'Item': 'Total Cooling Load', 'Value': f"{results.get('total_load', 0):.2f} W" }) report_data.append({ 'Section': 'Results', 'Item': 'Cooling Load per Area', 'Value': f"{results.get('total_load', 0) / building_info.get('floor_area', 1):.2f} W/m²" }) else: # heating report_data.append({ 'Section': 'Results', 'Item': 'Total Heating Load', 'Value': f"{results.get('total_load', 0):.2f} W" }) report_data.append({ 'Section': 'Results', 'Item': 'Heating Load per Area', 'Value': f"{results.get('total_load', 0) / building_info.get('floor_area', 1):.2f} W/m²" }) if 'annual_energy_kwh' in results: report_data.append({ 'Section': 'Results', 'Item': 'Annual Heating Energy', 'Value': f"{results.get('annual_energy_kwh', 0):.2f} kWh" }) # Create DataFrame df = pd.DataFrame(report_data) # Convert to HTML html = df.to_html(index=False) return html