Amfumu/solar-incentive-api
0
1"""2=============================================================================3Solar Incentive Intelligence API — Core Engine4=============================================================================5THE EDGE: IRA 2022 bonus adder stack — most developers only know about the630% base ITC. This engine correctly models all bonus adders that can push7the effective ITC to 50-70% in qualifying situations.8 9IRA 2022 Bonus Adder Stack:10 Base ITC: 30% §25D (residential) / §48 (commercial)11 Energy Community Bonus: +10% §48(a)(14) — coal closure / fossil fuel12 Domestic Content Bonus: +10% §48(a)(13) — US-manufactured equipment13 Low-Income Community Bonus: +10% §48(e) — Category 1 census tract14 Low-Income Benefit Bonus: +20% §48(e) — Category 2 affordable housing15 Maximum possible stack: 60% (residential §25D capped at 30%)16 17NOTE: The §48 commercial adders can stack to 50-60%.18 The §25D residential credit is capped at 30% but adders apply to §48E19 for residential clean energy in certain structures.20 21References:22 IRA 2022 Pub.L. 117-169 §§13101-1330223 IRS Notice 2023-29 (Energy Communities)24 IRS Notice 2023-38 (Domestic Content)25 IRS Revenue Procedure 2023-27 (Low-Income)26 Treasury Guidance §48(e) Final Rule (2024)27 DSIRE dsireusa.org (2024)28 SREC Trade (2024) — srectrack.com / srectrade.com29 EIA Form 861 (2023)30=============================================================================31"""32 33from typing import Dict, List, Optional, Tuple34import math35 36# ═══════════════════════════════════════════════════════════════════════════════37# IRA 2022 — BASE ITC SCHEDULE38# Source: IRA 2022 §25D (residential) and §48 (commercial)39# ═══════════════════════════════════════════════════════════════════════════════40 41ITC_SCHEDULE = {42 # year: (residential_§25D_pct, commercial_§48_pct)43 2022: (0.30, 0.30),44 2023: (0.30, 0.30),45 2024: (0.30, 0.30),46 2025: (0.30, 0.30),47 2026: (0.30, 0.30),48 2027: (0.30, 0.30),49 2028: (0.30, 0.30),50 2029: (0.30, 0.30),51 2030: (0.30, 0.30),52 2031: (0.30, 0.30),53 2032: (0.30, 0.30), # §25D expires after 203254 2033: (0.26, 0.26), # Step-down begins55 2034: (0.22, 0.22),56 2035: (0.00, 0.10), # §25D expires; §48 continues at 10%57}58 59ITC_ALERT_YEARS = {60 2025: "30% ITC under 2025 Congressional review. Locking in 2025 recommended. Source: SEIA Federal Policy Tracker (2025)",61 2032: "Final year of 30% §25D residential credit before step-down to 26%. Source: IRA 2022 §25D(g)",62 2033: "ITC stepped down to 26%. Install by Dec 31 2032 for 30% rate. Source: IRA 2022",63 2034: "ITC stepped down to 22%. Source: IRA 2022",64 2035: "Residential §25D ITC expires. Commercial §48 continues at 10%. Source: IRA 2022",65}66 67# ═══════════════════════════════════════════════════════════════════════════════68# IRA BONUS ADDERS69# Source: IRA 2022 §48(a)(13), §48(a)(14), §48(e)70# ═══════════════════════════════════════════════════════════════════════════════71 72# Energy Community Bonus — +10% adder for projects in:73# (a) Brownfield sites74# (b) Statistical areas with 0.17%+ direct employment in fossil fuels OR75# 0.25%+ local tax revenues from fossil fuels76# (c) Census tracts where coal mine/coal power plant closed after 199977# Source: IRS Notice 2023-29; Treasury §48(a)(14) Final Rule (2024)78 79ENERGY_COMMUNITY_STATES = {80 # States with highest concentration of qualifying energy communities81 # Source: IRS Energy Community Tool (energycommunities.gov)82 # Note: County-level eligibility required for precise determination83 "WV": {"probability": "high", "note": "Coal belt — most counties qualify", "fossil_employment_pct": 4.2},84 "KY": {"probability": "high", "note": "Coal belt — eastern KY MSAs qualify", "fossil_employment_pct": 3.8},85 "WY": {"probability": "high", "note": "Coal mining and oil/gas dominant", "fossil_employment_pct": 8.1},86 "ND": {"probability": "high", "note": "Oil/gas and lignite coal regions", "fossil_employment_pct": 5.6},87 "MT": {"probability": "high", "note": "Coal and oil/gas regions", "fossil_employment_pct": 3.1},88 "PA": {"probability": "medium", "note": "Anthracite coal belt and Pittsburgh MSA", "fossil_employment_pct": 2.1},89 "OH": {"probability": "medium", "note": "Appalachian Ohio coal closure communities", "fossil_employment_pct": 1.8},90 "IN": {"probability": "medium", "note": "Coal power plant closures", "fossil_employment_pct": 1.6},91 "TX": {"probability": "medium", "note": "Permian Basin and Eagle Ford (fossil employment)", "fossil_employment_pct": 2.4},92 "LA": {"probability": "medium", "note": "Gulf Coast fossil fuel employment", "fossil_employment_pct": 2.8},93 "OK": {"probability": "medium", "note": "Oil/gas employment MSAs", "fossil_employment_pct": 2.9},94 "CO": {"probability": "medium", "note": "Western slope coal regions", "fossil_employment_pct": 1.4},95 "NM": {"probability": "medium", "note": "Four Corners coal closure communities", "fossil_employment_pct": 2.2},96 "AK": {"probability": "medium", "note": "North Slope oil/gas employment", "fossil_employment_pct": 3.4},97 "AL": {"probability": "low", "note": "Some coal closure census tracts", "fossil_employment_pct": 0.9},98 "IL": {"probability": "low", "note": "Southern IL coal communities", "fossil_employment_pct": 0.8},99 "VA": {"probability": "low", "note": "Southwest VA coal communities", "fossil_employment_pct": 0.7},100 "AZ": {"probability": "low", "note": "Navajo Generating Station closure area", "fossil_employment_pct": 0.6},101}102 103# Domestic Content Bonus — +10% adder104# Steel, iron, and manufactured products must meet US content thresholds105# Source: IRS Notice 2023-38; Treasury §48(a)(13) Proposed Rule106DOMESTIC_CONTENT = {107 "base_adder_pct": 0.10,108 "steel_iron_req": 1.00, # 100% US steel/iron required109 "manufactured_req": 0.40, # 40% US manufactured products (rising to 55% by 2027)110 "manufactured_req_2027": 0.55,111 "qualifying_brands": [112 "First Solar (CdTe — US manufactured in Ohio)",113 "Qcells USA (Georgia manufacturing plant — partial)",114 "Mission Solar (Texas — US manufactured)",115 "Silfab Solar (Washington/Ontario — partial US content)",116 ],117 "source": "IRS Notice 2023-38; IRA 2022 §48(a)(13)",118 "note": (119 "Domestic content adder requires manufacturer certification. "120 "First Solar Series 6/7 CdTe panels manufactured in Perrysburg OH "121 "are the most straightforward qualifying option. "122 "Korean/Chinese panels do NOT qualify regardless of US assembly."123 ),124}125 126# Low-Income Community Bonus127# Category 1: +10% — located in low-income community (LIC census tract)128# Category 2: +20% — serves low-income residential building / housing facility129# Source: IRS Revenue Procedure 2023-27; IRA 2022 §48(e)130# Annual capacity allocation: 1.8 GW/yr total (700MW Cat1 + 200MW Cat2 + 900MW Indian land)131LOW_INCOME_BONUS = {132 "category_1": {133 "adder_pct": 0.10,134 "description": "Project located in low-income community census tract",135 "definition": "Census tract with poverty rate >= 20% or median income <= 80% of AMI",136 "allocation": "700 MW annual DOE allocation",137 "source": "IRA 2022 §48(e)(2)(A)(i); Rev. Proc. 2023-27",138 "application": "Annual DOE application required — not automatic",139 },140 "category_2": {141 "adder_pct": 0.20,142 "description": "Project serves low-income residential building or housing facility",143 "definition": "Federally subsidised housing, Section 8, or affordable housing project",144 "allocation": "200 MW annual DOE allocation",145 "source": "IRA 2022 §48(e)(2)(A)(ii); Rev. Proc. 2023-27",146 "application": "Annual DOE application required — not automatic",147 },148 "indian_land": {149 "adder_pct": 0.10,150 "description": "Project located on Indian land",151 "definition": "Tribal land as defined under §168(j)(4)(A)",152 "allocation": "900 MW annual DOE allocation",153 "source": "IRA 2022 §48(e)(2)(A)(iii)",154 },155}156 157# ═══════════════════════════════════════════════════════════════════════════════158# SREC MARKET — SOLAR RENEWABLE ENERGY CREDITS159# Source: SREC Trade srectrade.com; PJM-GATS; NEPOOL-GIS (2024)160# 1 SREC = 1 MWh of solar generation = 1,000 kWh161# ═══════════════════════════════════════════════════════════════════════════════162 163SREC_MARKETS = {164 # state: {active, price_per_srec, programme, expiry, notes}165 "NJ": {166 "active": True,167 "price_usd": 235, # Q4 2024 spot price — srectrade.com168 "programme": "NJ SREC-II (Successor SREC Programme)",169 "compliance_year": "June–May",170 "srecs_per_mwh": 1,171 "expiry": "Ongoing — SREC-II through 2033",172 "registry": "PJM-GATS",173 "source": "NJBPU Order March 2021; srectrade.com Q4 2024",174 "note": "NJ has one of the most lucrative SREC markets in the US. 10-year SREC contracts available.",175 },176 "MA": {177 "active": True,178 "price_usd": 285, # SMART programme incentive equivalent Q4 2024179 "programme": "MA SMART (Solar Massachusetts Renewable Target)",180 "compliance_year": "Calendar",181 "srecs_per_mwh": 1,182 "expiry": "Block-based — currently Block 5",183 "registry": "NEPOOL-GIS",184 "source": "MA DPU Order 17-140-C; DOER SMART tracker Q4 2024",185 "note": "MA SMART is a fixed incentive ($/kWh adder) not a tradeable SREC but functionally equivalent. Rates decline with each block.",186 },187 "DC": {188 "active": True,189 "price_usd": 395, # Highest SREC prices in the country190 "programme": "DC SREC Programme",191 "compliance_year": "Calendar",192 "srecs_per_mwh": 1,193 "expiry": "Ongoing",194 "registry": "PJM-GATS",195 "source": "DC PSC; srectrade.com Q4 2024",196 "note": "DC has the highest SREC prices in the US due to very aggressive RPS with solar carve-out and limited local generation.",197 },198 "MD": {199 "active": True,200 "price_usd": 65,201 "programme": "MD SREC Programme",202 "compliance_year": "June–May",203 "srecs_per_mwh": 1,204 "expiry": "Ongoing",205 "registry": "PJM-GATS",206 "source": "MD PSC; srectrade.com Q4 2024",207 },208 "PA": {209 "active": True,210 "price_usd": 20,211 "programme": "PA SREC Programme",212 "compliance_year": "June–May",213 "srecs_per_mwh": 1,214 "expiry": "Ongoing",215 "registry": "PJM-GATS",216 "source": "PA PUC; srectrade.com Q4 2024",217 "note": "PA SREC prices are low due to weak RPS solar carve-out.",218 },219 "OH": {220 "active": True,221 "price_usd": 12,222 "programme": "OH SREC Programme",223 "compliance_year": "Calendar",224 "srecs_per_mwh": 1,225 "expiry": "Ongoing",226 "registry": "PJM-GATS",227 "source": "OH PUCO; srectrade.com Q4 2024",228 },229 "IL": {230 "active": True,231 "price_usd": 75,232 "programme": "IL Adjustable Block Programme (ABP)",233 "compliance_year": "Calendar",234 "srecs_per_mwh": 1,235 "expiry": "Block-based",236 "registry": "GATS",237 "source": "IL Commerce Commission; IPA ABP tracker Q4 2024",238 "note": "IL ABP is a 15-year fixed incentive. New blocks open periodically.",239 },240 "CT": {241 "active": True,242 "price_usd": 18,243 "programme": "CT ZREC/LREC Programme",244 "compliance_year": "Calendar",245 "srecs_per_mwh": 1,246 "expiry": "Ongoing",247 "registry": "NEPOOL-GIS",248 "source": "CT PURA; NEPOOL-GIS Q4 2024",249 },250 "DE": {251 "active": True,252 "price_usd": 30,253 "programme": "DE SREC Programme",254 "compliance_year": "June–May",255 "srecs_per_mwh": 1,256 "expiry": "Ongoing",257 "registry": "PJM-GATS",258 "source": "DE PSC; srectrade.com Q4 2024",259 },260 "NY": {261 "active": True,262 "price_usd": 0, # NY uses VDER/CDG credit not tradeable SRECs263 "programme": "NY Value of Distributed Energy Resources (VDER)",264 "compliance_year": "N/A",265 "srecs_per_mwh": 0,266 "expiry": "Ongoing",267 "registry": "NYGATS",268 "source": "NYPSC Case 15-E-0751",269 "note": "NY replaced SRECs with VDER stack payments. Not tradeable but valued in NEM calculation.",270 },271 "VA": {272 "active": True,273 "price_usd": 40,274 "programme": "VA REC Programme",275 "compliance_year": "Calendar",276 "srecs_per_mwh": 1,277 "expiry": "Ongoing",278 "registry": "PJM-GATS",279 "source": "VA SCC; srectrade.com Q4 2024",280 },281 "NC": {282 "active": True,283 "price_usd": 8,284 "programme": "NC REPS Solar REC",285 "compliance_year": "Calendar",286 "srecs_per_mwh": 1,287 "expiry": "Ongoing",288 "registry": "NC-RETS",289 "source": "NC Utilities Commission; Q4 2024",290 },291 "WA": {292 "active": False,293 "price_usd": 0,294 "programme": "WA has no active SREC market",295 "note": "WA uses Production Incentive Programme (expired 2020)",296 "source": "WA UTC",297 },298 "CA": {299 "active": False,300 "price_usd": 0,301 "programme": "CA has no SREC market",302 "note": "CA uses NEM and SGIP battery incentive instead of SRECs",303 "source": "CPUC",304 },305 "TX": {306 "active": False,307 "price_usd": 0,308 "programme": "TX has no state SREC market",309 "note": "TX RECs (TRECs) have minimal value ~$0.50-2.00. No solar carve-out.",310 "source": "ERCOT",311 },312 "FL": {313 "active": False,314 "price_usd": 0,315 "programme": "FL has no SREC market",316 "source": "FL PSC",317 },318 "AZ": {319 "active": False,320 "price_usd": 0,321 "programme": "AZ has no active SREC market",322 "source": "AZ ACC",323 },324 "HI": {325 "active": False,326 "price_usd": 0,327 "programme": "HI has no SREC market",328 "source": "HI PUC",329 },330}331 332# ═══════════════════════════════════════════════════════════════════════════════333# STATE REBATE + GRANT DATABASE334# Source: DSIRE dsireusa.org (2024); utility programme websites335# ═══════════════════════════════════════════════════════════════════════════════336 337STATE_REBATES = {338 "NY": {339 "programmes": [340 {341 "name": "NYSERDA NY-Sun Incentive",342 "amount_per_w": 0.20,343 "max_kw": 25,344 "type": "rebate",345 "paid_to": "installer (passed to customer)",346 "source": "NYSERDA NY-Sun Programme (2024)",347 "status": "active",348 "note": "Block-based incentive. Amount varies by utility territory and block.",349 },350 ],351 "tax_credits": [352 {353 "name": "NY Solar Energy System Equipment Tax Credit",354 "pct": 0.25,355 "max_usd": 5000,356 "type": "state_income_tax_credit",357 "form": "IT-255",358 "source": "NY Tax Law §606(g-1) (2024)",359 },360 ],361 "exemptions": [362 {"type": "sales_tax", "pct": 1.0, "source": "NY Tax Law §1115(kk) (2024)"},363 {"type": "property_tax", "yrs": 15, "source": "NY Real Property Tax Law §487 (2024)"},364 ],365 },366 "MA": {367 "programmes": [368 {369 "name": "MA SMART Programme",370 "amount_kwh": 0.12, # Base incentive varies by block and utility371 "term_years": 10,372 "type": "production_incentive",373 "source": "MA DPU Order 17-140-C; DOER SMART Programme",374 "status": "active_block_5",375 "note": "Fixed per-kWh payment for 10 years. Rate declines each block. Check current block status.",376 },377 {378 "name": "MassSave Heat Pump + Solar Bundle",379 "amount": 3000,380 "type": "rebate",381 "source": "MassSave Programme (2024)",382 "note": "Available when solar paired with qualifying heat pump.",383 },384 ],385 "tax_credits": [386 {387 "name": "MA Residential Solar Tax Credit",388 "pct": 0.15,389 "max_usd": 1000,390 "type": "state_income_tax_credit",391 "source": "MA G.L. c.62 §6(d) (2024)",392 },393 ],394 "exemptions": [395 {"type": "sales_tax", "pct": 1.0, "source": "MA G.L. c.64H §6(dd) (2024)"},396 {"type": "property_tax", "yrs": 20, "source": "MA G.L. c.59 §5(45) (2024)"},397 ],398 },399 "CA": {400 "programmes": [401 {402 "name": "SGIP Battery Storage Incentive",403 "amount": 0.15, # $/Wh for equity resilience projects404 "type": "battery_rebate",405 "source": "CPUC SGIP Programme (2024)",406 "note": "For battery storage paired with solar. Equity resilience projects prioritised. Not a solar-only rebate.",407 },408 ],409 "tax_credits": [],410 "exemptions": [411 {"type": "property_tax", "yrs": 10, "source": "CA Revenue & Taxation Code §73 (2024)"},412 ],413 },414 "AZ": {415 "programmes": [],416 "tax_credits": [417 {418 "name": "AZ Solar Energy Credit",419 "pct": 0.25,420 "max_usd": 1000,421 "type": "state_income_tax_credit",422 "source": "ARS §43-1083.01 (2024)",423 },424 ],425 "exemptions": [426 {"type": "sales_tax", "pct": 1.0, "source": "ARS §42-5061(A)(46) (2024)"},427 {"type": "property_tax", "yrs": None, "source": "ARS §42-11054 (2024)", "note": "Full value exemption"},428 ],429 },430 "HI": {431 "programmes": [],432 "tax_credits": [433 {434 "name": "HI Renewable Energy Technologies Income Tax Credit",435 "pct": 0.35,436 "max_usd": 5000,437 "type": "state_income_tax_credit",438 "source": "HRS §235-12.5 (2024)",439 "note": "Capped at $5,000 per system per year. Can carry forward.",440 },441 ],442 "exemptions": [443 {"type": "property_tax", "yrs": None, "source": "HRS §246-34 (2024)"},444 ],445 },446 "NJ": {447 "programmes": [448 {449 "name": "NJ Successor Solar Incentive Programme (SuSI)",450 "type": "srec_programme",451 "note": "See SREC market data. Residential systems receive SREC-II certificates.",452 "source": "NJBPU SuSI Programme (2024)",453 },454 ],455 "tax_credits": [],456 "exemptions": [457 {"type": "sales_tax", "pct": 1.0, "source": "NJ Rev. Stat. §54:32B-8.32 (2024)"},458 {"type": "property_tax", "yrs": None, "source": "NJ Rev. Stat. §54:4-3.113 (2024)"},459 ],460 },461 "TX": {462 "programmes": [463 {464 "name": "Austin Energy Value of Solar",465 "amount_kwh": 0.097,466 "type": "utility_vos",467 "source": "Austin Energy VOS Tariff (2024)",468 "note": "Austin Energy service territory only.",469 },470 ],471 "tax_credits": [],472 "exemptions": [473 {"type": "property_tax", "pct": 1.0, "source": "TX Tax Code §11.27 (2024)", "note": "Full appraised value exemption"},474 ],475 },476 "FL": {477 "programmes": [],478 "tax_credits": [],479 "exemptions": [480 {"type": "sales_tax", "pct": 1.0, "source": "FL Stat. §212.08(7)(hh) (2024)"},481 {"type": "property_tax", "yrs": None, "source": "FL Stat. §193.624 (2024)"},482 ],483 },484 "CO": {485 "programmes": [486 {487 "name": "Xcel Energy Solar*Rewards",488 "amount": 0.028, # $/kWh — varies by block489 "type": "production_incentive",490 "source": "Xcel Energy Solar*Rewards Programme (2024)",491 "note": "Xcel Energy territory only. 20-year contract.",492 },493 ],494 "tax_credits": [],495 "exemptions": [496 {"type": "sales_tax", "pct": 1.0, "source": "CO Rev. Stat. §39-26-724 (2024)"},497 {"type": "property_tax", "yrs": None, "source": "CO Rev. Stat. §39-3-118.5 (2024)"},498 ],499 },500 "OR": {501 "programmes": [502 {503 "name": "OR Residential Energy Tax Credit (RETC)",504 "max_usd": 6000,505 "type": "state_income_tax_credit",506 "source": "OR ORS §316.116 (2024)",507 "note": "Claimed over 4 years. $1,500/yr max.",508 },509 ],510 "tax_credits": [511 {512 "name": "OR RETC",513 "max_usd": 6000,514 "type": "state_income_tax_credit",515 "source": "OR ORS §316.116 (2024)",516 },517 ],518 "exemptions": [519 {"type": "property_tax", "yrs": None, "source": "OR ORS §307.175 (2024)"},520 ],521 },522 "MN": {523 "programmes": [524 {525 "name": "Xcel Energy Solar*Rewards MN",526 "amount": 0.08,527 "type": "production_incentive",528 "source": "Xcel Energy MN Solar*Rewards (2024)",529 "note": "Xcel territory only. 10-year contract.",530 },531 ],532 "tax_credits": [],533 "exemptions": [534 {"type": "sales_tax", "pct": 1.0, "source": "MN Stat. §297A.67 (2024)"},535 ],536 },537 "IL": {538 "programmes": [539 {540 "name": "IL Adjustable Block Programme (ABP)",541 "type": "srec_programme",542 "note": "15-year fixed incentive. See SREC market data.",543 "source": "IL Commerce Commission; IPA ABP (2024)",544 },545 ],546 "tax_credits": [],547 "exemptions": [548 {"type": "property_tax", "yrs": None, "source": "35 ILCS 200/10-22 (2024)"},549 ],550 },551 "MD": {552 "programmes": [553 {554 "name": "MEA Residential Clean Energy Rebate",555 "amount": 1000,556 "type": "rebate",557 "source": "MD MEA Clean Energy Grant Programme (2024)",558 },559 ],560 "tax_credits": [],561 "exemptions": [562 {"type": "property_tax", "yrs": None, "source": "MD Tax-Property §9-203 (2024)"},563 {"type": "sales_tax", "pct": 1.0, "source": "MD Tax-General §11-213 (2024)"},564 ],565 },566 "_DEFAULT": {567 "programmes": [],568 "tax_credits": [],569 "exemptions": [],570 },571}572 573# ═══════════════════════════════════════════════════════════════════════════════574# INTERCONNECTION QUEUE STATUS575# Source: FERC interconnection queue data; utility IRPs; LBNL (2024)576# ═══════════════════════════════════════════════════════════════════════════════577 578INTERCONNECTION_STATUS = {579 # utility_id: {wait_months, difficulty, notes}580 "PGE": {"utility": "Pacific Gas & Electric", "state": "CA", "wait_months": 36, "difficulty": "severe", "note": "PG&E queue backlog ~18GW. Average 3-year wait. Source: FERC Q3 2024"},581 "SCE": {"utility": "Southern California Edison", "state": "CA", "wait_months": 24, "difficulty": "high", "note": "SCE NEM 3.0 transition slowing queue. Source: FERC Q3 2024"},582 "SDGE": {"utility": "San Diego Gas & Electric", "state": "CA", "wait_months": 18, "difficulty": "medium", "note": "Source: FERC Q3 2024"},583 "FPL": {"utility": "Florida Power & Light", "state": "FL", "wait_months": 6, "difficulty": "low", "note": "FL has relatively smooth interconnection. Source: FERC Q3 2024"},584 "DUKE_NC":{"utility": "Duke Energy Carolinas", "state": "NC", "wait_months": 12, "difficulty": "medium", "note": "Duke queue growing with utility-scale. Residential faster. Source: FERC Q3 2024"},585 "CON_ED": {"utility": "Consolidated Edison", "state": "NY", "wait_months": 12, "difficulty": "medium", "note": "Con Ed NYC territory has grid constraints. Source: FERC Q3 2024"},586 "COMED": {"utility": "Commonwealth Edison", "state": "IL", "wait_months": 8, "difficulty": "low", "note": "Source: FERC Q3 2024"},587 "APS": {"utility": "Arizona Public Service", "state": "AZ", "wait_months": 8, "difficulty": "low", "note": "APS has been improving interconnection. Source: FERC Q3 2024"},588 "HECO": {"utility": "Hawaiian Electric", "state": "HI", "wait_months": 18, "difficulty": "high", "note": "HI grid constraints significant. CGSP export limits. Source: FERC Q3 2024"},589 "PSEG": {"utility": "Public Service Electric & Gas","state": "NJ", "wait_months": 10, "difficulty": "medium", "note": "Source: FERC Q3 2024"},590 "BGE": {"utility": "Baltimore Gas & Electric", "state": "MD", "wait_months": 8, "difficulty": "low", "note": "Source: FERC Q3 2024"},591 "EVERSOURCE_MA": {"utility": "Eversource MA", "state": "MA", "wait_months": 12, "difficulty": "medium", "note": "Source: FERC Q3 2024"},592 "XCEL_CO":{"utility": "Xcel Energy Colorado", "state": "CO", "wait_months": 6, "difficulty": "low", "note": "Source: FERC Q3 2024"},593 "TVA": {"utility": "Tennessee Valley Authority", "state": "TN", "wait_months": 4, "difficulty": "low", "note": "TVA no NEM but quick interconnection. Source: FERC Q3 2024"},594}595 596# ═══════════════════════════════════════════════════════════════════════════════597# CORE CALCULATION FUNCTIONS598# ═══════════════════════════════════════════════════════════════════════════════599 600def calculate_itc_stack(601 state: str,602 system_cost: float,603 install_year: int,604 system_type: str = "residential", # "residential" or "commercial"605 energy_community: bool = False,606 domestic_content: bool = False,607 low_income_category: Optional[int] = None, # None, 1, or 2608 indian_land: bool = False,609) -> Dict:610 """611 Calculate the complete IRA ITC stack including all bonus adders.612 613 For residential §25D: base credit only (30%), adders apply to §48E614 For commercial §48: full adder stack available615 616 Source: IRA 2022 §25D, §48, §48(a)(13), §48(a)(14), §48(e)617 """618 schedule = ITC_SCHEDULE.get(install_year, ITC_SCHEDULE[2026])619 base_pct = schedule[0] if system_type == "residential" else schedule[1]620 621 adders = []622 total_adder_pct = 0.0623 624 # Commercial systems get all adders; residential §25D capped at 30%625 if system_type == "commercial":626 if energy_community:627 adders.append({628 "name": "Energy Community Bonus",629 "pct": 0.10,630 "source": "IRA 2022 §48(a)(14); IRS Notice 2023-29",631 "note": "Project located in qualifying energy community (brownfield, coal closure, or fossil fuel employment area)",632 })633 total_adder_pct += 0.10634 635 if domestic_content:636 adders.append({637 "name": "Domestic Content Bonus",638 "pct": 0.10,639 "source": "IRA 2022 §48(a)(13); IRS Notice 2023-38",640 "note": "All steel/iron US-made; manufactured products meet 40%+ US content threshold",641 })642 total_adder_pct += 0.10643 644 if low_income_category == 1:645 adders.append({646 "name": "Low-Income Community Bonus — Category 1",647 "pct": 0.10,648 "source": "IRA 2022 §48(e)(2)(A)(i); Rev. Proc. 2023-27",649 "note": "Project in low-income community census tract. DOE annual application required.",650 })651 total_adder_pct += 0.10652 elif low_income_category == 2:653 adders.append({654 "name": "Low-Income Community Bonus — Category 2",655 "pct": 0.20,656 "source": "IRA 2022 §48(e)(2)(A)(ii); Rev. Proc. 2023-27",657 "note": "Project serves low-income residential building or affordable housing. DOE annual application required.",658 })659 total_adder_pct += 0.20660 661 if indian_land:662 adders.append({663 "name": "Indian Land Bonus",664 "pct": 0.10,665 "source": "IRA 2022 §48(e)(2)(A)(iii)",666 "note": "Project located on tribal land as defined under §168(j)(4)(A)",667 })668 total_adder_pct += 0.10669 670 else:671 # Residential §25D — base 30% only; note adders for awareness672 if energy_community or domestic_content or low_income_category or indian_land:673 adders.append({674 "name": "Note: Residential §25D Credit",675 "pct": 0.0,676 "source": "IRA 2022 §25D",677 "note": (678 "The §25D residential credit is fixed at 30% and does not "679 "include bonus adders. Bonus adders (energy community, "680 "domestic content, low-income) apply to the §48 commercial "681 "credit. For commercial or multi-family systems, consider "682 "filing under §48 to access bonus adders."683 ),684 })685 686 effective_pct = min(base_pct + total_adder_pct, 0.60) # theoretical max 60%687 itc_amount = system_cost * effective_pct688 base_amount = system_cost * base_pct689 adder_amount = system_cost * total_adder_pct690 691 alert = ITC_ALERT_YEARS.get(install_year)692 693 return {694 "system_type": system_type,695 "install_year": install_year,696 "system_cost": system_cost,697 "base_itc_pct": base_pct,698 "base_itc_amount": round(base_amount, 2),699 "bonus_adder_pct": round(total_adder_pct, 2),700 "bonus_adder_amount": round(adder_amount, 2),701 "effective_itc_pct": round(effective_pct, 2),702 "effective_itc_amount":round(itc_amount, 2),703 "net_cost": round(system_cost - itc_amount, 2),704 "adders_applied": adders,705 "form": "IRS Form 5695 (residential) or Form 3468 (commercial)",706 "source": "IRA 2022 Pub.L. 117-169 §§13101-13302",707 "policy_alert": alert,708 }709 710 711def calculate_srec_revenue(712 state: str,713 annual_kwh: float,714 system_years: int = 10,715 price_escalation: float = 0.0, # annual price change assumption716) -> Dict:717 """718 Calculate SREC revenue over system lifetime.719 1 SREC = 1 MWh = 1,000 kWh720 Source: SREC Trade srectrade.com; PJM-GATS; NEPOOL-GIS (2024)721 """722 market = SREC_MARKETS.get(state.upper())723 724 if not market:725 return {726 "state": state,727 "srec_market": False,728 "reason": "No SREC market data available for this state",729 "annual_srecs": 0,730 "annual_revenue": 0,731 }732 733 if not market["active"] or market["price_usd"] == 0:734 return {735 "state": state,736 "srec_market": False,737 "programme": market.get("programme", "None"),738 "reason": market.get("note", "No active SREC market"),739 "annual_srecs": 0,740 "annual_revenue": 0,741 "source": market.get("source", "DSIRE 2024"),742 }743 744 annual_srecs = annual_kwh / 1000.0 # Convert kWh to MWh → SRECs745 year_revenues = []746 total_revenue = 0.0747 price = market["price_usd"]748 749 for yr in range(1, system_years + 1):750 rev = annual_srecs * price * (1 + price_escalation) ** (yr - 1)751 # Apply 0.5%/yr production degradation752 rev *= (0.995 ** (yr - 1))753 year_revenues.append({"year": yr, "srecs": round(annual_srecs * (0.995**(yr-1)), 2),754 "price_usd": round(price * (1+price_escalation)**(yr-1), 0),755 "revenue_usd": round(rev, 2)})756 total_revenue += rev757 758 return {759 "state": state,760 "srec_market": True,761 "programme": market["programme"],762 "current_price_usd":market["price_usd"],763 "annual_srecs": round(annual_srecs, 2),764 "annual_revenue_yr1":round(annual_srecs * market["price_usd"], 2),765 "total_revenue_10yr":round(total_revenue, 2),766 "year_by_year": year_revenues,767 "note": market.get("note"),768 "source": market.get("source", "SREC Trade (2024)"),769 "registry": market.get("registry"),770 }771 772 773def get_energy_community_eligibility(state: str) -> Dict:774 """775 Return energy community eligibility assessment for a state.776 County-level determination requires IRS Energy Community mapping tool.777 Source: IRS Notice 2023-29; energycommunities.gov778 """779 ec = ENERGY_COMMUNITY_STATES.get(state.upper())780 if not ec:781 return {782 "state": state,783 "probability": "unknown",784 "bonus_pct": 0.10,785 "note": "Energy community status requires county-level lookup at energycommunities.gov",786 "source": "IRS Notice 2023-29; IRA 2022 §48(a)(14)",787 }788 return {789 "state": state,790 "probability": ec["probability"],791 "fossil_employment_pct": ec["fossil_employment_pct"],792 "bonus_if_qualifying": 0.10,793 "note": ec["note"],794 "action": "Verify exact parcel eligibility at energycommunities.gov",795 "source": "IRS Notice 2023-29; IRA 2022 §48(a)(14); DOE Energy Community Tool",796 }797 798 799def get_full_incentive_stack(800 state: str,801 system_cost: float,802 system_kw: float,803 install_year: int,804 annual_kwh: float,805 system_type: str = "residential",806 energy_community: bool = False,807 domestic_content: bool = False,808 low_income_category: Optional[int] = None,809 include_interconnection: bool = False,810 utility_id: Optional[str] = None,811) -> Dict:812 """813 Master function — returns the complete incentive picture for a project.814 """815 # ITC stack816 itc = calculate_itc_stack(817 state, system_cost, install_year, system_type,818 energy_community, domestic_content, low_income_category819 )820 821 # State rebates + credits822 state_data = STATE_REBATES.get(state.upper(), STATE_REBATES["_DEFAULT"])823 824 # Quantify state rebate825 state_rebate_total = 0.0826 for prog in state_data.get("programmes", []):827 if prog.get("amount_per_w"):828 state_rebate_total += prog["amount_per_w"] * system_kw * 1000829 elif prog.get("amount"):830 state_rebate_total += prog["amount"]831 832 # Quantify state tax credits833 state_credit_total = 0.0834 for credit in state_data.get("tax_credits", []):835 if credit.get("pct"):836 raw = system_cost * credit["pct"]837 state_credit_total += min(raw, credit.get("max_usd", raw))838 elif credit.get("max_usd"):839 state_credit_total += credit["max_usd"]840 841 # SREC revenue842 srec = calculate_srec_revenue(state, annual_kwh)843 844 # Energy community eligibility845 ec_eligibility = get_energy_community_eligibility(state)846 847 # Interconnection848 intercon = None849 if include_interconnection and utility_id:850 intercon = INTERCONNECTION_STATUS.get(utility_id.upper())851 852 # Totals853 total_dollar_incentives = (854 itc["effective_itc_amount"]855 + state_rebate_total856 + state_credit_total857 )858 net_cost = system_cost - total_dollar_incentives859 srec_10yr = srec.get("total_revenue_10yr", 0)860 total_value_10yr = total_dollar_incentives + srec_10yr861 862 return {863 "project": {864 "state": state,865 "system_cost": system_cost,866 "system_kw": system_kw,867 "install_year": install_year,868 "system_type": system_type,869 "annual_kwh": annual_kwh,870 },871 "federal_itc": itc,872 "state_incentives": state_data,873 "state_rebate_total": round(state_rebate_total, 2),874 "state_credit_total": round(state_credit_total, 2),875 "srec_market": srec,876 "energy_community": ec_eligibility,877 "domestic_content_info": DOMESTIC_CONTENT,878 "low_income_info": LOW_INCOME_BONUS,879 "interconnection": intercon,880 "summary": {881 "gross_system_cost": round(system_cost, 2),882 "federal_itc": round(itc["effective_itc_amount"], 2),883 "effective_itc_pct": round(itc["effective_itc_pct"] * 100, 1),884 "state_rebates": round(state_rebate_total, 2),885 "state_tax_credits": round(state_credit_total, 2),886 "total_upfront_incentives": round(total_dollar_incentives, 2),887 "net_cost_after_incentives": round(net_cost, 2),888 "srec_revenue_10yr": round(srec_10yr, 2),889 "total_value_10yr": round(total_value_10yr, 2),890 "incentive_coverage_pct": round((total_dollar_incentives / system_cost) * 100, 1),891 },892 }893 