CoolFace
Apppublic

Amfumu/solar-incentive-api

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
incentive_engine.py893 linesDownload Raw Back to root
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