/* RENOVAM — Calculator v2 (HSP real + bloques CFE + Panel 640W) */ const { useState, useMemo } = React; // ============ TARIFAS CFE (bloques bimestrales) ============ const TARIFAS = { 1: { bas: 150, int: 280, pBas: 0.95, pInt: 1.17, pExc: 3.51 }, '1A': { bas: 175, int: 300, pBas: 0.95, pInt: 1.17, pExc: 3.51 }, '1B': { bas: 200, int: 400, pBas: 0.95, pInt: 1.17, pExc: 3.51 }, '1C': { bas: 225, int: 600, pBas: 0.95, pInt: 1.17, pExc: 3.51 }, '1D': { bas: 275, int: 700, pBas: 0.95, pInt: 1.17, pExc: 3.51 }, '1E': { bas: 300, int: 1000,pBas: 0.95, pInt: 1.17, pExc: 3.51 }, '1F': { bas: 375, int: 1300,pBas: 0.95, pInt: 1.17, pExc: 3.51 }, }; const DAP_BIM = 62; const IVA = 1.16; const PANEL_W = 640; // Trinasolar 640W const PMAX_CORR = 0.5965; // kW corregido por temperatura (640W × 0.932) const DIAS_BIM = 60; const COSTO_POR_PANEL = 8750; // MXN instalado // ============ HSP por estado/municipio con tarifa CFE ============ // Tarifas asignadas según tabla CFE oficial: // 1 <25°C · CDMX, Edomex, Puebla, Tlaxcala, Hidalgo, Querétaro, zonas altas // 1A =25°C · Morelos (zonas altas), Jalisco interior, Guanajuato, partes de Veracruz y SLP // 1B =28°C · Morelos cálido, Tamaulipas norte, Veracruz, NL, cálidas moderadas // 1C =30°C · Monterrey, Sinaloa, Nayarit, Colima, costas Jalisco, Cancún // 1D =31°C · Yucatán, Campeche, Tabasco, Tamaulipas/Veracruz muy cálidos // 1E =32°C · Partes Sonora, Campeche, Yucatán, tropicales extremas // 1F ≥33°C · Mexicali, Hermosillo, San Luis Río Colorado, desérticas Sonora/BC const HSP_DATA = { "CDMX": { "Centro / Cuauhtémoc / BJ": { hsp: 5.35, tarifa: 1 }, "Sur (Xochimilco / Tlalpan / Milpa Alta)": { hsp: 5.64, tarifa: 1 }, "Norte (Gustavo A. Madero / Azcapotzalco)": { hsp: 5.64, tarifa: 1 }, "Iztapalapa / Iztacalco": { hsp: 5.35, tarifa: 1 }, "Álvaro Obregón / Coyoacán": { hsp: 5.50, tarifa: 1 }, }, "Morelos": { "Oaxtepec / Cuautla": { hsp: 6.19, tarifa: '1B' }, "Cuernavaca": { hsp: 5.89, tarifa: '1A' }, "Jojutla / Sur de Morelos": { hsp: 5.89, tarifa: '1B' }, "Temixco": { hsp: 5.95, tarifa: '1A' }, "Yautepec": { hsp: 6.05, tarifa: '1B' }, }, "Estado de México": { "Naucalpan": { hsp: 5.35, tarifa: 1 }, "Ecatepec": { hsp: 5.35, tarifa: 1 }, "Cuautitlán Izcalli": { hsp: 5.65, tarifa: 1 }, "Nezahualcóyotl": { hsp: 5.35, tarifa: 1 }, "Toluca": { hsp: 5.35, tarifa: 1 }, "Texcoco": { hsp: 5.45, tarifa: 1 }, "Chalco / Valle de Chalco": { hsp: 5.45, tarifa: 1 }, "Tlalnepantla": { hsp: 5.40, tarifa: 1 }, "Metepec": { hsp: 5.40, tarifa: 1 }, }, "Puebla": { "Puebla (ciudad)": { hsp: 5.70, tarifa: 1 }, "Tehuacán": { hsp: 5.85, tarifa: '1A' }, "San Martín Texmelucan": { hsp: 5.60, tarifa: 1 }, "Atlixco": { hsp: 5.75, tarifa: '1A' }, "Cholula": { hsp: 5.70, tarifa: 1 }, "Izúcar de Matamoros": { hsp: 5.80, tarifa: '1B' }, "Huauchinango": { hsp: 5.40, tarifa: 1 }, "Zacatlán": { hsp: 5.35, tarifa: 1 }, }, "Tlaxcala": { "Tlaxcala (ciudad)": { hsp: 5.55, tarifa: 1 }, "Apizaco": { hsp: 5.50, tarifa: 1 }, "Huamantla": { hsp: 5.60, tarifa: 1 }, "Zacatelco": { hsp: 5.55, tarifa: 1 }, "Chiautempan": { hsp: 5.50, tarifa: 1 }, }, "Hidalgo": { "Pachuca": { hsp: 5.50, tarifa: 1 }, "Tulancingo": { hsp: 5.45, tarifa: 1 }, "Tizayuca": { hsp: 5.40, tarifa: 1 }, "Actopan": { hsp: 5.55, tarifa: 1 }, "Tula de Allende": { hsp: 5.50, tarifa: 1 }, "Huejutla de Reyes": { hsp: 5.30, tarifa: '1B' }, "Ixmiquilpan": { hsp: 5.55, tarifa: 1 }, }, "Guerrero": { "Acapulco": { hsp: 5.90, tarifa: '1D' }, "Chilpancingo": { hsp: 5.80, tarifa: '1B' }, "Iguala": { hsp: 6.00, tarifa: '1B' }, "Taxco": { hsp: 6.00, tarifa: '1A' }, "Zihuatanejo / Ixtapa": { hsp: 5.60, tarifa: '1D' }, "Tlapa de Comonfort": { hsp: 5.70, tarifa: '1A' }, "Ometepec": { hsp: 5.65, tarifa: '1C' }, }, "Querétaro": { "Querétaro (ciudad)": { hsp: 5.74, tarifa: 1 }, "San Juan del Río": { hsp: 5.70, tarifa: 1 }, "El Marqués": { hsp: 5.72, tarifa: 1 } }, "Jalisco": { "Guadalajara": { hsp: 5.87, tarifa: '1A' }, "Zapopan": { hsp: 5.85, tarifa: '1A' }, "Tlaquepaque": { hsp: 5.87, tarifa: '1A' }, "Puerto Vallarta": { hsp: 5.80, tarifa: '1C' } }, "Nuevo León": { "Monterrey": { hsp: 5.70, tarifa: '1C' }, "San Pedro Garza García": { hsp: 5.68, tarifa: '1B' }, "Apodaca / Santa Catarina": { hsp: 5.65, tarifa: '1C' } }, "Veracruz": { "Xalapa": { hsp: 5.57, tarifa: '1A' }, "Veracruz (puerto)": { hsp: 5.57, tarifa: '1C' }, "Coatzacoalcos": { hsp: 5.40, tarifa: '1D' }, "Córdoba / Orizaba": { hsp: 5.50, tarifa: '1A' } }, "Oaxaca": { "Oaxaca (ciudad)": { hsp: 5.74, tarifa: '1A' }, "Salina Cruz": { hsp: 5.90, tarifa: '1D' }, "Huatulco": { hsp: 5.85, tarifa: '1D' } }, "Guanajuato": { "León": { hsp: 5.76, tarifa: '1A' }, "Celaya": { hsp: 5.72, tarifa: '1A' }, "Irapuato": { hsp: 5.70, tarifa: '1A' }, "Salamanca": { hsp: 5.68, tarifa: '1A' } }, "Michoacán": { "Morelia": { hsp: 5.88, tarifa: 1 }, "Uruapan": { hsp: 5.80, tarifa: '1A' }, "Zamora": { hsp: 5.75, tarifa: '1A' } }, "San Luis Potosí": { "San Luis Potosí (ciudad)": { hsp: 5.83, tarifa: '1A' }, "Ciudad Valles": { hsp: 5.70, tarifa: '1C' } }, "Sonora": { "Hermosillo": { hsp: 6.20, tarifa: '1F' }, "Ciudad Obregón": { hsp: 6.30, tarifa: '1E' }, "Nogales": { hsp: 6.10, tarifa: '1B' } }, "Chihuahua": { "Chihuahua (ciudad)": { hsp: 5.66, tarifa: '1C' }, "Juárez": { hsp: 5.80, tarifa: '1D' }, "Delicias": { hsp: 5.70, tarifa: '1D' } }, "Baja California": { "Tijuana": { hsp: 5.92, tarifa: '1B' }, "Mexicali": { hsp: 6.30, tarifa: '1F' }, "Ensenada": { hsp: 5.85, tarifa: '1A' } }, "Baja California Sur": { "La Paz": { hsp: 6.10, tarifa: '1E' }, "Los Cabos": { hsp: 6.20, tarifa: '1E' } }, "Sinaloa": { "Culiacán": { hsp: 5.83, tarifa: '1C' }, "Mazatlán": { hsp: 5.85, tarifa: '1C' }, "Los Mochis": { hsp: 5.80, tarifa: '1C' } }, "Coahuila": { "Saltillo": { hsp: 5.53, tarifa: '1A' }, "Torreón": { hsp: 5.80, tarifa: '1D' }, "Monclova": { hsp: 5.55, tarifa: '1C' } }, "Tamaulipas": { "Tampico": { hsp: 5.92, tarifa: '1D' }, "Reynosa": { hsp: 5.90, tarifa: '1D' }, "Matamoros": { hsp: 5.88, tarifa: '1D' } }, "Yucatán": { "Mérida": { hsp: 5.72, tarifa: '1D' }, "Valladolid": { hsp: 5.65, tarifa: '1D' } }, "Quintana Roo": { "Cancún": { hsp: 5.62, tarifa: '1C' }, "Playa del Carmen": { hsp: 5.55, tarifa: '1C' }, "Tulum": { hsp: 5.58, tarifa: '1C' } }, "Tabasco": { "Villahermosa": { hsp: 5.60, tarifa: '1D' }, "Comalcalco": { hsp: 5.55, tarifa: '1D' } }, "Chiapas": { "Tuxtla Gutiérrez": { hsp: 5.68, tarifa: '1C' }, "San Cristóbal de las Casas": { hsp: 5.50, tarifa: 1 }, "Tapachula": { hsp: 5.60, tarifa: '1C' } }, "Zacatecas": { "Zacatecas (ciudad)": { hsp: 5.89, tarifa: 1 }, "Fresnillo": { hsp: 5.85, tarifa: 1 } }, "Durango": { "Durango (ciudad)": { hsp: 5.77, tarifa: 1 }, "Gómez Palacio": { hsp: 5.80, tarifa: '1C' } }, "Aguascalientes": { "Aguascalientes (ciudad)": { hsp: 5.90, tarifa: '1A' }, "Jesús María": { hsp: 5.88, tarifa: '1A' } }, "Nayarit": { "Tepic": { hsp: 5.89, tarifa: '1C' }, "Bahía de Banderas": { hsp: 5.85, tarifa: '1C' } }, "Colima": { "Colima (ciudad)": { hsp: 5.71, tarifa: '1C' }, "Manzanillo": { hsp: 5.60, tarifa: '1C' } }, "Campeche": { "Campeche (ciudad)": { hsp: 5.78, tarifa: '1D' }, "Ciudad del Carmen": { hsp: 5.72, tarifa: '1D' } }, }; const FUTURE_LOADS = [ { key: 'ev', icon: '⚡', label: 'Carro eléctrico (EV)', sub: '+400 kWh bimestral', kwh: 400 }, { key: 'ac', icon: '❄️', label: 'Aire acondicionado (1 equipo)', sub: '+250 kWh bimestral', kwh: 250 }, { key: 'hp', icon: '🔥', label: 'Bomba de calor', sub: '+180 kWh bimestral', kwh: 180 }, { key: 'wp', icon: '💧', label: 'Bomba de agua', sub: '+80 kWh bimestral', kwh: 80 }, { key: 'misc', icon: '💡', label: 'Más iluminación / electrodomésticos', sub: '+60 kWh bimestral', kwh: 60 }, ]; // ============ MOTOR DE CÁLCULO ============ function kwhDesdeRecibo(reciboBim, tarifa) { const b = TARIFAS[tarifa] || TARIFAS[1]; const subtotal = Math.max(0, (reciboBim - DAP_BIM) / IVA); const cosBas = b.bas * b.pBas; const cosInt = (b.int - b.bas) * b.pInt; if (subtotal <= cosBas) return subtotal / b.pBas; if (subtotal <= cosBas + cosInt) return b.bas + (subtotal - cosBas) / b.pInt; return b.int + (subtotal - cosBas - cosInt) / b.pExc; } function reciboDesdeKwh(kwh, tarifa) { const b = TARIFAS[tarifa] || TARIFAS[1]; if (kwh <= 0) return DAP_BIM; const sub = Math.min(kwh, b.bas) * b.pBas + Math.max(0, Math.min(kwh - b.bas, b.int - b.bas)) * b.pInt + Math.max(0, kwh - b.int) * b.pExc; return Math.round(sub * IVA + DAP_BIM); } function calcularPaneles(kwhTotal, hsp) { const consumoDiario = kwhTotal / DIAS_BIM; const potenciaPico = consumoDiario / hsp; const nExacto = potenciaPico / PMAX_CORR; const n = Math.round(nExacto / 2) * 2; return Math.max(4, Math.min(40, n)); } function calcularResultados(reciboBim, hsp, cargasExtra, tarifa) { const kwhHogar = kwhDesdeRecibo(reciboBim, tarifa); const kwhTotal = kwhHogar + cargasExtra; const nPaneles = calcularPaneles(kwhTotal, hsp); const kwSistema = +(nPaneles * (PANEL_W / 1000)).toFixed(2); const prodBim = Math.round(nPaneles * PMAX_CORR * hsp * DIAS_BIM); const kwhNeto = Math.max(0, kwhTotal - prodBim); const reciboConPaneles = reciboDesdeKwh(kwhNeto, tarifa); const ahorroBim = Math.max(0, reciboBim - reciboConPaneles); const ahorroAnual = ahorroBim * 6; const inversion = nPaneles * COSTO_POR_PANEL; const roi = ahorroAnual > 0 ? (inversion / ahorroAnual).toFixed(1) : '—'; const proyeccion = Array.from({ length: 11 }, (_, i) => ({ año: i, sinPaneles: Math.round(reciboBim * Math.pow(1.045, i)), conPaneles: Math.round(reciboConPaneles * Math.pow(1.04, i)), })); return { kwhHogar: Math.round(kwhHogar), kwhTotal: Math.round(kwhTotal), nPaneles, kwSistema, prodBim, kwhNeto: Math.round(kwhNeto), reciboConPaneles, ahorroBim, ahorroAnual, inversion, roi, co2: +(kwSistema * 1.4).toFixed(1), proyeccion, tarifa, hsp, }; } // ============ GRÁFICA SVG ============ function ProyeccionChart({ proyeccion }) { const [hover, setHover] = useState(null); const W = 760, H = 320, padL = 60, padR = 20, padT = 24, padB = 48; const innerW = W - padL - padR; const innerH = H - padT - padB; const years = proyeccion.map(p => p.año); const max = Math.max(...proyeccion.map(p => Math.max(p.sinPaneles, p.conPaneles))) * 1.1; const barW = innerW / years.length / 2.8; const groupW = innerW / years.length; const yTicks = 4; const ticks = Array.from({length: yTicks + 1}, (_, i) => max * i / yTicks); return (

Tu recibo en los próximos 10 años

Sin paneles (+4.5% / año) Con RENOVAM (+4% / año)
{ticks.map((t, i) => { const y = padT + innerH - (t / max) * innerH; return ( ${Math.round(t).toLocaleString('es-MX')} ); })} {proyeccion.map((p, i) => { const cx = padL + i * groupW + groupW / 2; const h1 = (p.sinPaneles / max) * innerH; const h2 = (p.conPaneles / max) * innerH; const isHover = hover === i; return ( setHover(i)} onMouseLeave={() => setHover(null)}> Año {p.año} {isHover && ( Año {p.año} Sin: ${p.sinPaneles.toLocaleString('es-MX')} Con: ${p.conPaneles.toLocaleString('es-MX')} )} ); })}
); } // ============ COMPONENTE PRINCIPAL ============ function Calculator() { const [step, setStep] = useState(0); const [bill, setBill] = useState(''); const [estado, setEstado] = useState(''); const [municipio, setMunicipio] = useState(''); const [loads, setLoads] = useState([]); const billNum = parseFloat(bill) || 0; const zona = estado && municipio ? HSP_DATA[estado]?.[municipio] : null; const hsp = zona?.hsp || 5.5; const tarifa = zona?.tarifa || 1; const cargasExtra = loads.reduce((s, k) => s + (FUTURE_LOADS.find(l => l.key === k)?.kwh || 0), 0); const r = useMemo( () => calcularResultados(Math.max(billNum, 500), hsp, cargasExtra, tarifa), [billNum, hsp, cargasExtra, tarifa] ); const toggleLoad = (k) => setLoads(cur => cur.includes(k) ? cur.filter(x => x !== k) : [...cur, k]); const step1Valid = billNum > 300 && estado && municipio; const municipios = estado ? Object.keys(HSP_DATA[estado] || {}) : []; const cargasLabels = loads.map(k => FUTURE_LOADS.find(l => l.key === k)?.label).filter(Boolean); const openWhatsApp = () => { const msg = encodeURIComponent( `Hola RENOVAM 👋 Usé la calculadora de su página y me interesa saber más.\n\n` + `📍 *Ubicación:* ${estado} — ${municipio}\n` + `💡 *Recibo bimestral:* $${billNum.toLocaleString('es-MX')} MXN\n` + `📊 *Consumo estimado:* ${r.kwhHogar.toLocaleString('es-MX')} kWh bimestral\n` + `⚡ *Sistema sugerido:* ${r.kwSistema} kW · ${r.nPaneles} paneles ${PANEL_W}W\n` + `💰 *Ahorro estimado:* $${r.ahorroAnual.toLocaleString('es-MX')} MXN/año\n` + `📅 *ROI:* ${r.roi} años\n` + (cargasLabels.length ? `🔌 *Cargas futuras:* ${cargasLabels.join(', ')}\n` : '') + `\n¿Me pueden dar una propuesta personalizada?` ); window.open(`https://wa.me/527778297622?text=${msg}`, '_blank'); }; const stepDefs = [ { title: 'Tu recibo CFE y ubicación', sub: 'Combinamos tu consumo bimestral con la radiación solar real (HSP) y la tarifa CFE de tu zona.', content: (
$ MXN setBill(e.target.value)} />

Busca "Total a pagar" en tu recibo bimestral.

{zona && (
📍 HSP zona{zona.hsp.toFixed(2)} kWh/m²/día · Tarifa CFE{zona.tarifa}
)}
), valid: () => step1Valid, }, { title: '¿Planeas agregar alguna de estas cargas en el futuro?', sub: 'Esto nos ayuda a dimensionar tu sistema con visión a largo plazo. Puedes saltar este paso.', content: (
{FUTURE_LOADS.map(l => ( ))}
), valid: () => true, }, { title: 'Tu propuesta personalizada', sub: 'Cifras estimadas con HSP real y tu tarifa CFE. Un ingeniero RENOVAM las afina en visita técnica gratuita.', content: (
Agendar instalación →
), valid: () => true, }, ]; const cur = stepDefs[step]; return (
Calculadora

Cuánto puedes ahorrar con energía solar.

Tres pasos. Cálculo realista con HSP por zona, bloques tarifarios CFE y panel Trinasolar {PANEL_W}W.

{['01','02','03'].map((n, i) => ( i?'done':''}`}>{n} ))}

{cur.title}

{cur.sub}

{cur.content}
{step > 0 && } {step < 2 && ( )}

Tu propuesta en vivo

${r.ahorroAnual.toLocaleString('es-MX')} /año ahorrados
Recibo bimestral SIN paneles ${Math.max(billNum, 0).toLocaleString('es-MX')} MXN cada 2 meses
Recibo bimestral CON paneles ${r.reciboConPaneles.toLocaleString('es-MX')} MXN cada 2 meses
💰 Ahorro anual${r.ahorroAnual.toLocaleString('es-MX')} MXN
⚡ Sistema sugerido{r.kwSistema} kW · {r.nPaneles} paneles
📊 Consumo estimado{r.kwhHogar.toLocaleString('es-MX')} kWh bim.
☀️ Producción sistema{r.prodBim.toLocaleString('es-MX')} kWh bim.
💵 Inversión estimada${r.inversion.toLocaleString('es-MX')} MXN
📅 Retorno de inversión{r.roi} años
🌱 CO₂ evitado/año{r.co2} ton
{zona && (
📍 {municipio}HSP {r.hsp} · Tarifa {r.tarifa}
)}

* Estimado con HSP real, bloques tarifarios CFE y panel Trinasolar {PANEL_W}W con factor de corrección térmica.

); } window.Calculator = Calculator;