Utility Bill Optimization Tool

Configure Your Utilities

Set up the utilities you want to track. This information will be saved in your browser.

Enter Utility Bill Data

Entered Bills for

No bills entered for this utility yet.

Analyze Consumption & Cost Trends

Select a configured utility with bill data to see analysis.

Optimization Scenarios & Estimator

Select a configured utility to explore scenarios. Appliance estimator is available for Electricity if configured.

Download Your Utility Report

The PDF report will include your utility configurations, detailed bill entries, trend analysis summaries (data and charts if possible), current "What-If" scenario results, and appliance estimations (if available).

(Appliance chart image not available)

`; } } } else { pdfHtml += "

No appliance data or Electricity rate not configured.

"; } pdfHtml += `
`; pdfHtml += `
`; // Close ubot-pdf-output const pdfOutputEl = toolContainer.querySelector('#ubot-pdfOutput'); if (pdfOutputEl) pdfOutputEl.innerHTML = pdfHtml; const opt = { margin: [0.5, 0.4, 0.5, 0.4], filename: `Utility_Optimization_Report_${new Date().toISOString().slice(0,10)}.pdf`, image: { type: 'jpeg', quality: 0.95 }, html2canvas: { scale: 2, useCORS: true, logging: false, scrollX: 0, scrollY: 0, windowWidth: pdfOutputEl ? pdfOutputEl.scrollWidth : 1200, windowHeight: pdfOutputEl ? pdfOutputEl.scrollHeight + 50 : 1600}, jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }, pagebreak: { mode: ['avoid-all', 'css', 'legacy'] } }; if (html2pdf && pdfOutputEl) { // Check if html2pdf is loaded and pdfOutputEl exists html2pdf().from(pdfOutputEl).set(opt).save() .catch(err => console.error("PDF generation failed:", err)); } else { alert("PDF generation library or output element not ready."); } }); // --- Tab Navigation --- window.ubot_openTab = function(evt, tabName) { tabs.forEach(tab => tab.style.display = 'none'); tabLinks.forEach(link => link.classList.remove('active')); const activeTabContent = toolContainer.querySelector('#' + tabName); if(activeTabContent) activeTabContent.style.display = 'block'; else { console.error(`Tab content for ${tabName} not found.`); return; } let clickedIndex = -1; if (evt && evt.currentTarget) { evt.currentTarget.classList.add('active'); clickedIndex = tabLinks.indexOf(evt.currentTarget); } else { clickedIndex = tabLinks.findIndex(link => { const onclickAttr = link.getAttribute('onclick'); return onclickAttr && onclickAttr.includes(tabName); }); if (clickedIndex !== -1) tabLinks[clickedIndex].classList.add('active'); } currentTabIndex = clickedIndex !== -1 ? clickedIndex : 0; ubot_updateNavButtons(); if (tabName === 'ubot-tab2') { if(billUtilitySelectEl.value) handleBillUtilitySelectChange(); } else if (tabName === 'ubot-tab3') { if(analysisUtilitySelectEl.value) ubot_renderAnalysis(); } else if (tabName === 'ubot-tab4') { if(optimizeUtilitySelectEl.value) ubot_setupOptimizationTab(); } } window.ubot_navigateTab = function(direction) { let newIndex = currentTabIndex; if (direction === 'next' && currentTabIndex < tabs.length - 1) newIndex++; else if (direction === 'prev' && currentTabIndex > 0) newIndex--; if (tabLinks[newIndex] && newIndex !== currentTabIndex) tabLinks[newIndex].click(); } function ubot_updateNavButtons() { if(prevButton) prevButton.disabled = currentTabIndex === 0; if(nextButton) nextButton.disabled = currentTabIndex >= tabs.length - 1; // >= in case tabs array is off } // --- Initialization --- function initializeTool() { if (!Chart || !html2pdf) { alert("Required libraries (Chart.js or html2pdf.js) not loaded. Some features may not work."); // return; // Or continue with degraded functionality } loadData(); renderUtilityConfigs(); populateUtilitySelects(); const today = new Date(); if(billPeriodEl) billPeriodEl.value = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}`; ubot_openTab(null, 'ubot-tab1'); } // Defensive check for Chart.js and html2pdf.js (if loaded via CDN, they might take time) let attempts = 0; function checkLibrariesAndInit() { if (typeof Chart !== 'undefined' && typeof html2pdf !== 'undefined') { initializeTool(); } else if (attempts < 20) { // Try for 2 seconds attempts++; setTimeout(checkLibrariesAndInit, 100); } else { alert("Error: Essential libraries (Chart.js, html2pdf.js) could not be loaded. Please check your internet connection or try again later. The tool may not function correctly."); // Fallback initialization without charts or PDF perhaps, or just show an error. // For now, it will proceed but chart/pdf functions will fail more gracefully due to checks. initializeTool(); // Try to init anyway, functions have internal checks } } checkLibrariesAndInit(); })();
Scroll to Top