SunFusion Quantum Calculator V5.1 SunFusion Quantum Calculator V5.1 Customer Information Customer Name Address Phone Email Utility Information Utility Provider Select Provider San Diego Gas & Electric Southern California Edison Pacific Gas & Electric Other Rate Plan Select Rate Plan TOU-DR1 TOU-DR2 EV-TOU Other Peak Rate (\$/kWh) Past 12 Months Highest kWh Past 12 Months Highest Peak kW Existing Solar System System Size (kW) Average Daily Production (kWh) Inverter Type Select Inverter Type String Inverter Microinverter Power Optimizer Other Inverter Model Arbitrage Partial Backup Whole Home Elite Basic - 16 kWh / 8 kW Elite Standard - 16 kWh / 12 kW Elite Prime - 16 kWh / 15 kW - + No Additional Inverter Sol-Ark 8K - 8kW Inverter Sol-Ark 12K - 12kW Inverter Sol-Ark 15K - 15kW Inverter - + Guardian Elite - 16kWh / 15kW 60A Limited Guardian E2.0 - 48kWh / 15kW 100A Limited // Initialize calculator namespace const calculator = { // System Configurations systems: { arbitrage: { basic: { name: 'Elite Basic', capacity: 16, power: 8, maxQty: 4, price: 8680.10, ampLimit: 40, recommendedMin: 800, // Minimum monthly kWh recommended recommendedMax: 1200 // Maximum monthly kWh recommended }, standard: { name: 'Elite Standard', capacity: 16, power: 12, maxQty: 4, price: 9980.10, ampLimit: 50, recommendedMin: 1000, recommendedMax: 1500 }, prime: { name: 'Elite Prime', capacity: 16, power: 15, maxQty: 4, price: 11750.10, ampLimit: 60, recommendedMin: 1200, recommendedMax: 1800 } }, partial: { 'elite-60': { name: 'Guardian Elite 16kWh/15kW', capacity: 16, power: 15, maxQty: 2, price: 11750.10, ampLimit: 60, recommendedMin: 1200, recommendedMax: 2000 }, 'e2-100': { name: 'Guardian E2.0 48kWh/15kW', capacity: 48, power: 15, maxQty: 2, price: 27373.26, ampLimit: 100, recommendedMin: 2000, recommendedMax: 3500 } }, 'whole-home': { 'e2-100': { name: 'Guardian E2.0 48kWh/15kW', capacity: 48, power: 15, maxQty: 12, price: 27373.26, ampLimit: 100, recommendedMin: 2000, recommendedMax: 3500 }, tower: { name: 'Guardian Tower 96kWh', capacity: 96, power: 15, maxQty: 30, price: 32210, ampLimit: 200, recommendedMin: 3500, recommendedMax: 7000 } } }, // Additional Inverter Options inverters: { 'solark-8k': { name: 'Sol-Ark 8K', power: 8, price: 6589, efficiency: 96.5, maxSolar: 11 }, 'solark-12k': { name: 'Sol-Ark 12K', power: 12, price: 7589, efficiency: 96.5, maxSolar: 16 }, 'solark-15k': { name: 'Sol-Ark 15K', power: 15, price: 8658, efficiency: 96.5, maxSolar: 20 } }, // Utility rate plans utilityRates: { 'sdge': { 'tou-dr1': { peak: 0.48, offPeak: 0.22, superOffPeak: 0.09 }, 'tou-dr2': { peak: 0.51, offPeak: 0.24, superOffPeak: 0.11 }, 'ev-tou': { peak: 0.45, offPeak: 0.20, superOffPeak: 0.08 } } }, // Utility Functions safeGetValue(elementId, defaultValue = 0) { const element = document.getElementById(elementId); return element ? (element.value || defaultValue) : defaultValue; }, getCustomerInfo() { return { name: this.safeGetValue('customer-name', ''), address: this.safeGetValue('customer-address', ''), phone: this.safeGetValue('customer-phone', ''), email: this.safeGetValue('customer-email', ''), utilityProvider: this.safeGetValue('utility-provider', ''), ratePlan: this.safeGetValue('rate-plan', '') }; }, getCurrentTab() { try { const activeTab = document.querySelector('.tab-btn.active'); return activeTab ? activeTab.dataset.tab : 'arbitrage'; } catch (error) { console.error('Error getting current tab:', error); return 'arbitrage'; } }, getUtilityInfo() { return { provider: this.safeGetValue('utility-provider', ''), ratePlan: this.safeGetValue('rate-plan', ''), peakRate: parseFloat(this.safeGetValue('peak-rate', 0.48)), highestKwh: parseFloat(this.safeGetValue('highest-kwh', 1200)), highestKw: parseFloat(this.safeGetValue('highest-kw', 7.5)) }; }, getExistingSolar() { return { size: parseFloat(this.safeGetValue('existing-solar', 0)), production: parseFloat(this.safeGetValue('solar-production', 0)), inverterType: this.safeGetValue('solar-inverter', ''), inverterModel: this.safeGetValue('inverter-model', '') }; }, // Core Calculation Functions calculateSystemRequirements(utilityInfo, existingSolar) { const dailyUsage = utilityInfo.highestKwh / 30; const peakPower = utilityInfo.highestKw; const existingProduction = existingSolar.production; return { recommendedCapacity: Math.max(dailyUsage * 0.7, peakPower * 4), recommendedPower: Math.max(peakPower * 1.2, 8), additionalSolar: Math.max(0, (dailyUsage - existingProduction) * 0.8 / 4.5) }; }, calculateSystem(type, model, quantity, additionalInverterModel, additionalInverterQty) { try { const system = this.systems[type][model]; const utilityInfo = this.getUtilityInfo(); const existingSolar = this.getExistingSolar(); const customerInfo = this.getCustomerInfo(); const totalCapacity = system.capacity * quantity; const totalPower = system.power * quantity; let additionalPower = 0; let additionalCost = 0; if (additionalInverterModel && additionalInverterQty > 0) { const inverter = this.inverters[additionalInverterModel]; additionalPower = inverter.power * additionalInverterQty; additionalCost = inverter.price * additionalInverterQty; } const requirements = this.calculateSystemRequirements(utilityInfo, existingSolar); const solarSize = this.calculateSolarRequirements(totalCapacity, totalPower + additionalPower, utilityInfo, existingSolar); const savings = this.calculateSavings(totalCapacity, utilityInfo, existingSolar); return { customer: customerInfo, system: { name: system.name, quantity: quantity, totalCapacity: totalCapacity, totalPower: totalPower + additionalPower, ampLimit: system.ampLimit * quantity, price: system.price * quantity, isRecommended: this.isRecommendedSystem(system, utilityInfo.highestKwh) }, additionalInverter: additionalInverterModel ? { name: this.inverters[additionalInverterModel].name, quantity: additionalInverterQty, power: additionalPower, price: additionalCost } : null, solar: { existing: existingSolar, additional: solarSize, totalSize: existingSolar.size + solarSize, dailyProduction: (existingSolar.size + solarSize) * 4.5, estimatedPrice: solarSize * 2800 }, requirements: requirements, savings: savings, utility: utilityInfo }; } catch (error) { console.error('Error calculating system:', error); return null; } }, calculateSolarRequirements(batteryCapacity, systemPower, utilityInfo, existingSolar) { // Calculate required solar based on multiple factors const dailyBatteryCharge = batteryCapacity * 1.2; // 120% of battery capacity for losses const peakPowerSupport = systemPower * 1.3; // 130% of system power for overhead const dailyUsage = utilityInfo.highestKwh / 30; // Calculate minimum required solar after existing system const existingProduction = existingSolar.production || (existingSolar.size * 4.5); const requiredProduction = Math.max( dailyBatteryCharge, dailyUsage * 0.8, // 80% of daily usage peakPowerSupport * 4 // 4 hours of peak power support ); // Additional solar needed after existing system const additionalSolar = Math.max(0, (requiredProduction - existingProduction) / 4.5 // 4.5 kWh per kW of solar ); return Math.ceil(additionalSolar * 10) / 10; // Round to 1 decimal place }, calculateSavings(batteryCapacity, utilityInfo, existingSolar) { // Daily arbitrage savings const arbitrageCycles = 1; // Once per day const arbitrageEfficiency = 0.92; // 92% round trip efficiency const peakOffset = utilityInfo.peakRate - 0.12; // Assume charging at \$0.12/kWh const dailyArbitrage = batteryCapacity * arbitrageCycles * arbitrageEfficiency * peakOffset; // Demand charge savings const demandSavings = utilityInfo.highestKw * 25; // Assume \$25/kW demand charge // Solar self-consumption savings const existingProduction = existingSolar.production || (existingSolar.size * 4.5); const solarSavings = existingProduction * 30 * utilityInfo.peakRate * 0.3; // 30% improved self-consumption return { daily: dailyArbitrage, monthly: (dailyArbitrage * 30) + demandSavings + solarSavings, annual: (dailyArbitrage * 365) + (demandSavings * 12) + (solarSavings * 12), breakdown: { arbitrage: dailyArbitrage * 30, demand: demandSavings, solar: solarSavings } }; }, isRecommendedSystem(system, monthlyUsage) { return monthlyUsage >= system.recommendedMin && monthlyUsage <= system.recommendedMax; }, getSuggestedSystem(utilityInfo) { const monthlyUsage = utilityInfo.highestKwh; const peakDemand = utilityInfo.highestKw; // Determine system category based on usage and demand let category; if (monthlyUsage <= 1200 && peakDemand <= 8) { category = 'arbitrage'; } else if (monthlyUsage <= 2500 && peakDemand <= 15) { category = 'partial'; } else { category = 'whole-home'; } // Find best matching system within category const systems = this.systems[category]; let bestMatch = null; let minDiff = Infinity; for (const [model, specs] of Object.entries(systems)) { const diff = Math.abs(monthlyUsage - (specs.recommendedMin + specs.recommendedMax) / 2); if (diff < minDiff) { minDiff = diff; bestMatch = { category: category, model: model, specs: specs }; } } return bestMatch; },