From 9c1f16114c937f9c66995ca4189305d65c1dc1b3 Mon Sep 17 00:00:00 2001 From: Ziming Date: Fri, 23 Oct 2026 18:11:07 -0400 Subject: [PATCH] Add Louisiana LIHEAP regular heating assistance Co-Authored-By: Claude Opus 5.5 --- changelog.d/la-liheap-wave1d.added.md | 1 + .../gov/states/la/lhc/liheap/elderly_age.yaml | 22 ++ .../lhc/liheap/eligibility/fpg_year_lag.yaml | 17 + .../la/lhc/liheap/eligibility/smi_rate.yaml | 20 + .../la/lhc/liheap/income/adult_age.yaml | 22 ++ .../la/lhc/liheap/income/sources/earned.yaml | 24 ++ .../lhc/liheap/income/sources/unearned.yaml | 42 ++ .../states/la/lhc/liheap/payment/amount.yaml | 48 +++ .../la/lhc/liheap/payment/burden_band.yaml | 42 ++ .../liheap/payment/energy_cost_sources.yaml | 27 ++ .../liheap/payment/priority_supplement.yaml | 17 + .../la/lhc/liheap/payment/size_group.yaml | 22 ++ .../liheap/payment/young_child_max_age.yaml | 16 + policyengine_us/programs.yaml | 10 +- .../eligibility/la_liheap_eligible.yaml | 326 ++++++++++++++++ .../eligibility/la_liheap_income_limit.yaml | 138 +++++++ .../income/la_liheap_countable_income.yaml | 304 +++++++++++++++ .../gov/states/la/lhc/liheap/la_liheap.yaml | 364 ++++++++++++++++++ .../la/lhc/liheap/la_liheap_energy_cost.yaml | 129 +++++++ .../liheap/eligibility/la_liheap_eligible.py | 65 ++++ .../eligibility/la_liheap_income_limit.py | 26 ++ .../income/la_liheap_countable_income.py | 68 ++++ .../gov/states/la/lhc/liheap/la_liheap.py | 62 +++ .../la/lhc/liheap/la_liheap_energy_cost.py | 41 ++ .../la/lhc/liheap/la_liheap_household_size.py | 22 ++ 25 files changed, 1874 insertions(+), 1 deletion(-) create mode 100644 changelog.d/la-liheap-wave1d.added.md create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/elderly_age.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/eligibility/fpg_year_lag.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/eligibility/smi_rate.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/income/adult_age.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/income/sources/earned.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/income/sources/unearned.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/payment/amount.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/payment/burden_band.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/payment/energy_cost_sources.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/payment/priority_supplement.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/payment/size_group.yaml create mode 100644 policyengine_us/parameters/gov/states/la/lhc/liheap/payment/young_child_max_age.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/eligibility/la_liheap_eligible.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/eligibility/la_liheap_income_limit.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/income/la_liheap_countable_income.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/la_liheap.yaml create mode 100644 policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/la_liheap_energy_cost.yaml create mode 100644 policyengine_us/variables/gov/states/la/lhc/liheap/eligibility/la_liheap_eligible.py create mode 100644 policyengine_us/variables/gov/states/la/lhc/liheap/eligibility/la_liheap_income_limit.py create mode 100644 policyengine_us/variables/gov/states/la/lhc/liheap/income/la_liheap_countable_income.py create mode 100644 policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap.py create mode 100644 policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap_energy_cost.py create mode 100644 policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap_household_size.py diff --git a/changelog.d/la-liheap-wave1d.added.md b/changelog.d/la-liheap-wave1d.added.md new file mode 100644 index 00000000000..bc1300a6783 --- /dev/null +++ b/changelog.d/la-liheap-wave1d.added.md @@ -0,0 +1 @@ +Add Louisiana LIHEAP regular heating assistance. diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/elderly_age.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/elderly_age.yaml new file mode 100644 index 00000000000..7f654393f34 --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/elderly_age.yaml @@ -0,0 +1,22 @@ +description: Louisiana treats household members at least this age as elderly for the priority group supplement and the utility allowance exemption under the Low Income Home Energy Assistance Program. +# The guide exempts "Applicants 60 years or older" from the utility allowance +# rule and names "Persons 60 years or older" as a priority group. Plan item 2.3 +# words the exemption as "over 60 years old"; the guide's 60-or-older wording +# is followed for both uses. No input names the applicant, so any counted +# member of this age qualifies. +values: + 2025-10-01: 60 + +metadata: + unit: year + period: year + label: Louisiana LIHEAP elderly age + reference: + - title: "Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Sections 4.1 C and 4.2 A #page 40-41" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=40 + - title: "Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Sections 4.1 C and 4.2 A #page 46,48" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=46 + - title: Louisiana FFY2026 Heating and Cooling Benefit Matrix, targeted priority groups + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/LA_BenefitMatrix_Heat-Cool_2026.pdf + - title: "Louisiana FY2026 LIHEAP State Plan, Sections 2.3-2.4 #page 9-10" + href: https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=9 diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/eligibility/fpg_year_lag.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/eligibility/fpg_year_lag.yaml new file mode 100644 index 00000000000..1e1f18c2ad5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/eligibility/fpg_year_lag.yaml @@ -0,0 +1,17 @@ +description: Louisiana uses the federal poverty guidelines from this many years before the model year for the federal income floor under the Low Income Home Energy Assistance Program. +# HHS made the 2025 guidelines mandatory for LIHEAP from October 1, 2025, so +# model period 2026 (FY2026) uses the 2025 guidelines and 2027 the 2026 +# guidelines. Louisiana sets its limit at 60% of state median income; the +# guidelines enter only through the 110% floor of 42 U.S.C. 8624(b)(2)(B). +values: + 2025-10-01: 1 + +metadata: + unit: year + period: year + label: Louisiana LIHEAP poverty guideline year lag + reference: + - title: LIHEAP IM 2025-02, Attachment 2, poverty guidelines for mandatory use in FY26 + href: https://acf.gov/sites/default/files/documents/ocs/COMM_LIHEAP_IM2025-02_FPGSte-Table_Att2.pdf#page=1 + - title: 42 U.S.C. 8624(b)(2)(B) + href: https://www.law.cornell.edu/uscode/text/42/8624#b_2_B diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/eligibility/smi_rate.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/eligibility/smi_rate.yaml new file mode 100644 index 00000000000..5a6410f20b7 --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/eligibility/smi_rate.yaml @@ -0,0 +1,20 @@ +description: Louisiana limits heating assistance income to this share of state median income under the Low Income Home Energy Assistance Program. +# The FFY2026 notice prints the resulting limits for household sizes 1-10. +# No adopted FFY2027 plan is available; later years carry this rate forward +# as unverified estimates. +values: + 2025-10-01: 0.6 + +metadata: + unit: /1 + period: year + label: Louisiana LIHEAP state median income rate + reference: + - title: Louisiana FY2026 LIHEAP State Plan, Section 2.1 + href: https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=9 + - title: Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Section 3.6 C.1 + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=29 + - title: Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Section 3.6 C.1 + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=34 + - title: Louisiana Notice LHP-2025-01, LIHEAP Income Eligibility Limits for FFY2026 + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Notice%20LHP-2025-01%20-%20LIHEAP%20Income%20Eligibility%20Limits%20for%20FFY2026%20-%20LOUISIANA.pdf diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/income/adult_age.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/income/adult_age.yaml new file mode 100644 index 00000000000..8d677441d0a --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/income/adult_age.yaml @@ -0,0 +1,22 @@ +description: Louisiana counts the income of household members at least this age, while members under it count only Social Security and Supplemental Security Income, under the Low Income Home Energy Assistance Program. +# The guide counts "Any income of a household member age 18 and older". +# Appendix E counts Social Security benefits, including SSI, "paid to minors", +# and FAQ A4 counts the Social Security a parent receives for a minor child; +# no other income of a minor is counted. Appendix E also excludes income earned +# by members 18 and over still enrolled in high school (is_in_k12_school). +values: + 2025-10-01: 18 + +metadata: + unit: year + period: year + label: Louisiana LIHEAP adult age + reference: + - title: "Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Section 3.6 C.1 and Appendix E #page 29,82,85" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=29 + - title: "Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Section 3.6 C.1 and Appendix E #page 35,89,92" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=35 + - title: Louisiana LIHEAP Service Delivery Guide FAQs, February 11, 2022, A4 + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20Frequently%20Asked%20Questions%20(FAQs)%20-%202%2011%2022.pdf#page=2 + - title: Louisiana FY2026 LIHEAP State Plan, Section 1.9 + href: https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=6 diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/income/sources/earned.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/income/sources/earned.yaml new file mode 100644 index 00000000000..ffeed750d63 --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/income/sources/earned.yaml @@ -0,0 +1,24 @@ +description: Louisiana counts these sources as earned income of adult members not enrolled in high school under the Low Income Home Energy Assistance Program. +# The guide counts gross wages, salaries and commissions, military pay and net +# receipts from self-employment (self-employment income less business +# expenses). The existing net business inputs get no further deduction, and +# each source is floored at zero, so a loss in one source cannot offset another. +values: + 2025-10-01: + - employment_income + - self_employment_income + - sstb_self_employment_income + - farm_operations_income + - partnership_s_corp_income + +metadata: + unit: list + period: year + label: Louisiana LIHEAP earned income sources + reference: + - title: "Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Section 3.6 C.1 and Appendix E #page 29-30,82,84-85" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=29 + - title: "Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Section 3.6 C.1 and Appendix E #page 34-35,89,91-92" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=34 + - title: "Louisiana FY2026 LIHEAP State Plan, Sections 1.8-1.9 #page 5-7" + href: https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=5 diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/income/sources/unearned.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/income/sources/unearned.yaml new file mode 100644 index 00000000000..d0c6a301a2c --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/income/sources/unearned.yaml @@ -0,0 +1,42 @@ +description: Louisiana counts these sources as unearned income of adult members under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: + # Government and private pensions, annuities and insurance payments. + - pension_income + # Includes survivor benefit plan annuities. + - military_retirement_income + - railroad_benefits + - survivor_benefits + - veterans_benefits + - workers_compensation + - disability_benefits + - total_unemployment_compensation + - strike_benefits + - alimony_income + - interest_income + - ordinary_dividend_income + # The guide counts net rental income. + - rental_income + - farm_rent_income + # Periodic receipts from estates or trusts. + - estate_income + # Regular contributions that are not loans; existing inputs do not + # separate regular from irregular gifts. + - financial_assistance +# Social Security net of the Medicare Part B premium and SSI count for every +# member, and net gambling winnings and FITAP are added, in +# la_liheap_countable_income. The guide excludes child support, capital gains, +# bank and retirement-account withdrawals, tax refunds and SNAP. Royalties, +# jury duty pay, military family allotments, training stipends and informal +# income have no existing input. +metadata: + unit: list + period: year + label: Louisiana LIHEAP unearned income sources + reference: + - title: "Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Section 3.6 C.1 and Appendix E #page 29-30,81,83-86" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=29 + - title: "Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Section 3.6 C.1 and Appendix E #page 34-36,88,90-93" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=34 + - title: "Louisiana FY2026 LIHEAP State Plan, Sections 1.8-1.9 #page 5-7" + href: https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=5 diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/amount.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/amount.yaml new file mode 100644 index 00000000000..c7eab5d6ccc --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/amount.yaml @@ -0,0 +1,48 @@ +description: Louisiana provides this regular heating benefit by energy burden band and household size group under the Low Income Home Energy Assistance Program. +# The matrix prints one amount for sizes 1-3 and another for sizes 4 through +# "8 or More". The FY2026 plan's $200 minimum and $800 maximum (Section 2.6) +# equal the lowest cell and the highest cell plus the $100 priority supplement. +# Energy burden band 1: 9.9% and less. +1: + 1: + 2025-10-01: 200 + 2: + 2025-10-01: 250 +# Energy burden band 2: 10% to 17.9%. +2: + 1: + 2025-10-01: 350 + 2: + 2025-10-01: 400 +# Energy burden band 3: 18% to 24.9%. +3: + 1: + 2025-10-01: 500 + 2: + 2025-10-01: 550 +# Energy burden band 4: 25% and greater. +4: + 1: + 2025-10-01: 650 + 2: + 2025-10-01: 700 + +metadata: + unit: currency-USD + period: year + label: Louisiana LIHEAP regular heating benefit amount + breakdown: + - range(1, 5) # energy burden band + - range(1, 3) # household size group (1 = size 1-3, 2 = size 4+) + breakdown_labels: + - Energy burden band + - Household size group + reference: + - title: Louisiana FFY2026 Heating and Cooling Benefit Matrix, benefit amount + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/LA_BenefitMatrix_Heat-Cool_2026.pdf + - title: Louisiana FY2026 LIHEAP State Plan, Sections 2.4-2.6 + href: https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=10 + - title: Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Section 4.2 + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=41 + - title: Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Section 4.2 + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=48 diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/burden_band.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/burden_band.yaml new file mode 100644 index 00000000000..afc0262c8b6 --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/burden_band.yaml @@ -0,0 +1,42 @@ +description: Louisiana assigns this benefit matrix energy burden band from total energy cost as a share of countable income under the Low Income Home Energy Assistance Program. +# The matrix prints the bands as "9.9% and Less", "10% to 17.9%", "18% to +# 24.9%" and "25% and Greater". The unrounded burden uses lower-inclusive +# cutoffs at 10%, 18% and 25%, which equals truncating the percent to one +# decimal. Households with zero income receive band 4 in la_liheap. +brackets: + # 9.9% and less. + - threshold: + 2025-10-01: 0 + amount: + 2025-10-01: 1 + # 10% to 17.9%. + - threshold: + 2025-10-01: 0.1 + amount: + 2025-10-01: 2 + # 18% to 24.9%. + - threshold: + 2025-10-01: 0.18 + amount: + 2025-10-01: 3 + # 25% and greater. + - threshold: + 2025-10-01: 0.25 + amount: + 2025-10-01: 4 + +metadata: + type: single_amount + threshold_unit: /1 + amount_unit: /1 + period: year + label: Louisiana LIHEAP energy burden band + reference: + - title: Louisiana FFY2026 Heating and Cooling Benefit Matrix, energy burden percent + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/LA_BenefitMatrix_Heat-Cool_2026.pdf + - title: Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Section 4.2 + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=41 + - title: Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Section 4.2 + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=48 + - title: Louisiana FY2026 LIHEAP State Plan, Section 2.4 + href: https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=10 diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/energy_cost_sources.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/energy_cost_sources.yaml new file mode 100644 index 00000000000..f3a7937ced1 --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/energy_cost_sources.yaml @@ -0,0 +1,27 @@ +description: Louisiana adds these residential energy bills to compute the total energy cost under the Low Income Home Energy Assistance Program. +# The guide adds the bills of every energy vendor. Annual amounts stand in for +# the application-month bill; the ratio to annual income gives the same +# burden. Bill line items the guide includes or excludes (taxes, customer +# charges, franchise fees, arrears, deposits) cannot be separated from these +# totals. Community solar participants report their electric bill. +values: + 2025-10-01: + - pre_subsidy_electricity_expense + - gas_expense + - bottled_gas_expense + - fuel_oil_expense + - wood_expense + - coal_expense + - other_heating_fuel_expense + +metadata: + unit: list + period: year + label: Louisiana LIHEAP total energy cost sources + reference: + - title: "Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Section 4.1 #page 37-38" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=37 + - title: "Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Section 4.1 #page 43-44" + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=43 + - title: Louisiana FY2026 LIHEAP State Plan, Sections 2.4-2.5 + href: https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=10 diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/priority_supplement.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/priority_supplement.yaml new file mode 100644 index 00000000000..f3548178ea5 --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/priority_supplement.yaml @@ -0,0 +1,17 @@ +description: Louisiana adds this heating payment once per household with at least one member in a targeted priority group under the Low Income Home Energy Assistance Program. +values: + 2025-10-01: 100 + +metadata: + unit: currency-USD + period: year + label: Louisiana LIHEAP priority group supplement + reference: + - title: Louisiana FFY2026 Heating and Cooling Benefit Matrix, additional payment to targeted priority groups + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/LA_BenefitMatrix_Heat-Cool_2026.pdf + - title: Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Section 4.2 A + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=41 + - title: Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Section 4.2 A + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=48 + - title: Louisiana FY2026 LIHEAP State Plan, Section 2.4 + href: https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=10 diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/size_group.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/size_group.yaml new file mode 100644 index 00000000000..9ea95de21bd --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/size_group.yaml @@ -0,0 +1,22 @@ +description: Louisiana assigns this benefit matrix household size group from the number of counted household members under the Low Income Home Energy Assistance Program. +brackets: + # Household size 1-3. + - threshold: + 2025-10-01: 0 + amount: + 2025-10-01: 1 + # Household size 4 and over. + - threshold: + 2025-10-01: 4 + amount: + 2025-10-01: 2 + +metadata: + type: single_amount + threshold_unit: person + amount_unit: /1 + period: year + label: Louisiana LIHEAP household size group + reference: + - title: Louisiana FFY2026 Heating and Cooling Benefit Matrix, household size + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/LA_BenefitMatrix_Heat-Cool_2026.pdf diff --git a/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/young_child_max_age.yaml b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/young_child_max_age.yaml new file mode 100644 index 00000000000..97436bc5977 --- /dev/null +++ b/policyengine_us/parameters/gov/states/la/lhc/liheap/payment/young_child_max_age.yaml @@ -0,0 +1,16 @@ +description: Louisiana includes household members no older than this age in the young-child priority group under the Low Income Home Energy Assistance Program. +# "Persons five years of age and younger." +values: + 2025-10-01: 5 + +metadata: + unit: year + period: year + label: Louisiana LIHEAP young child priority group maximum age + reference: + - title: Louisiana FFY2026 Heating and Cooling Benefit Matrix, targeted priority groups + href: https://liheapch.acf.gov/docs/2026/benefits-matricies/LA_BenefitMatrix_Heat-Cool_2026.pdf + - title: Louisiana LIHEAP Service Delivery Guide, revised January 1, 2024, Section 4.2 A + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=41 + - title: Louisiana LIHEAP Service Delivery Guide, effective April 1, 2026, Section 4.2 A + href: https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=48 diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 43fdd714b80..81169f85345 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -808,7 +808,7 @@ programs: category: Benefits agency: HHS status: partial - coverage: AL, DC, Riverside County, MA, FL, IL, IN, KS, KY, MD, MS, NC, NE, NJ, NY, OH, OK, OR, SD, RI, TX + coverage: AL, DC, Riverside County, MA, FL, IL, IN, KS, KY, LA, MD, MS, NC, NE, NJ, NY, OH, OK, OR, SD, RI, TX state_implementations: - state: AL status: partial @@ -890,6 +890,14 @@ programs: parameter_prefix: gov.states.ky.dcbs.liheap verified_years: "2025-2026" notes: FY2025-FY2026 regular heating only, from the published benefit workbooks. Crisis and cooling assistance are out of scope. + - state: LA + status: partial + name: Louisiana LIHEAP + full_name: Louisiana Low Income Home Energy Assistance Program + variable: la_liheap + parameter_prefix: gov.states.la.lhc.liheap + verified_years: "2026" + notes: FY2026 regular heating-season benefit from the energy burden matrix, including the $100 priority supplement. The summer cooling cycle, crisis and weatherization assistance are out of scope. - state: MD status: partial name: Maryland MEAP diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/eligibility/la_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/eligibility/la_liheap_eligible.yaml new file mode 100644 index 00000000000..b7bdf0ec577 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/eligibility/la_liheap_eligible.yaml @@ -0,0 +1,326 @@ +# Service Delivery Guide (rev. January 1, 2024): income must not exceed the limit +# (page 33), a household of only ineligible aliens does not qualify (page 33), +# the applicant must be responsible for energy costs (page 35), and a subsidized +# household whose utility allowance exceeds its bill is ineligible unless a member +# is 60 or older (page 40). 42 U.S.C. 8624(b)(2)(B) protects income below 110% of +# the poverty guideline (2025 guidelines in FFY2026: 15,650 + 5,500 per extra person). +# Wages of 15,080 are full-time work at the federal 7.25 minimum wage; electricity of +# 1,740 is about the EIA 2024 Louisiana average residential bill of 145 a month. + +- name: Case 1, income exactly at the size-one limit is eligible. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 30_618 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + output: + la_liheap_eligible: true + +- name: Case 2, income one dollar above the size-one limit is ineligible. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 30_619 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + output: + la_liheap_eligible: false + +- name: Case 3, a thirteen-person household above the limit is not protected by the poverty floor. + period: 2026 + input: + people: + # Limit 90,089; floor (15,650 + 5,500 x 12) x 1.1 = 89,815. + person1: {age: 45, employment_income: 90_090} + person2: {age: 43} + person3: {age: 17} + person4: {age: 16} + person5: {age: 15} + person6: {age: 14} + person7: {age: 13} + person8: {age: 12} + person9: {age: 11} + person10: {age: 10} + person11: {age: 9} + person12: {age: 8} + person13: {age: 7} + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13] + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 900 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13] + state_code: LA + output: + la_liheap_eligible: false + +- name: Case 4, a fourteen-person household above the limit but below the poverty floor is eligible. + period: 2026 + input: + people: + # Limit 91,855; floor (15,650 + 5,500 x 13) x 1.1 = 95,865. + person1: {age: 45, employment_income: 95_864} + person2: {age: 43} + person3: {age: 17} + person4: {age: 16} + person5: {age: 15} + person6: {age: 14} + person7: {age: 13} + person8: {age: 12} + person9: {age: 11} + person10: {age: 10} + person11: {age: 9} + person12: {age: 8} + person13: {age: 7} + person14: {age: 6} + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 900 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: LA + output: + la_liheap_eligible: true + +- name: Case 5, income equal to 110 percent of the poverty guideline is not protected. + period: 2026 + input: + people: + # The floor protects income less than 95,865 only. + person1: {age: 45, employment_income: 95_865} + person2: {age: 43} + person3: {age: 17} + person4: {age: 16} + person5: {age: 15} + person6: {age: 14} + person7: {age: 13} + person8: {age: 12} + person9: {age: 11} + person10: {age: 10} + person11: {age: 9} + person12: {age: 8} + person13: {age: 7} + person14: {age: 6} + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 900 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: LA + output: + la_liheap_eligible: false + +- name: Case 6, a household with no heating bill and no heat in rent is ineligible. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 0 + heat_expense_included_in_rent: false + households: + household: + members: [person1] + state_code: LA + output: + la_liheap_eligible: false + +- name: Case 7, a home with no heating is ineligible. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + heating_type: NONE + pre_subsidy_electricity_expense: 1_740 + # Heat in rent passes the responsibility test, so only the NONE fuel gate fails. + heat_expense_included_in_rent: true + households: + household: + members: [person1] + state_code: LA + output: + la_liheap_eligible: false + +- name: Case 8, an unknown heating fuel with heat included in rent is eligible. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + heating_type: UNSPECIFIED + heat_expense_included_in_rent: true + households: + household: + members: [person1] + state_code: LA + output: + la_liheap_eligible: true + +- name: Case 9, an unknown heating fuel without heat in rent is ineligible. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + heating_type: UNSPECIFIED + pre_subsidy_electricity_expense: 1_740 + heat_expense_included_in_rent: false + households: + household: + members: [person1] + state_code: LA + output: + la_liheap_eligible: false + +- name: Case 10, a subsidized household whose bill exceeds its utility allowance is eligible. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + receives_housing_assistance: true + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + # Section 8 utility allowance of 100 a month; energy cost 1,740 - 1,200 = 540. + hud_utility_allowance: 1_200 + output: + la_liheap_eligible: true + +- name: Case 11, a subsidized household whose utility allowance equals its bill is ineligible. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + receives_housing_assistance: true + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + # Energy cost 1,740 - 1,740 = 0 shows no energy burden. + hud_utility_allowance: 1_740 + output: + la_liheap_eligible: false + +- name: Case 12, a subsidized 60-year-old is exempt from the utility allowance test. + period: 2026 + input: + people: + person1: + age: 60 + pension_income: 14_400 + spm_units: + spm_unit: + members: [person1] + receives_housing_assistance: true + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_500 + households: + household: + members: [person1] + state_code: LA + # No deduction at 60 or older, so energy cost stays 1,500 despite the 1,800 allowance. + hud_utility_allowance: 1_800 + output: + la_liheap_eligible: true + +- name: Case 13, a household of only undocumented members is ineligible. + period: 2026 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + output: + la_liheap_eligible: false + +- name: Case 14, a household outside Louisiana is ineligible. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: TX + output: + la_liheap_eligible: false diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/eligibility/la_liheap_income_limit.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/eligibility/la_liheap_income_limit.yaml new file mode 100644 index 00000000000..b0297860e1b --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/eligibility/la_liheap_income_limit.yaml @@ -0,0 +1,138 @@ +# FFY2026 limit is 60% of the Louisiana state median income (Notice LHP-2025-01). +# Four-person limit: floor(98,137 x 0.6) = 58,882; each size uses +# floor(58,882 x factor), with factors 0.52 + 0.16 per person through six +# and 0.03 for each person above six (sizes 11 and up are not published). + +- name: Case 1, an undocumented member is excluded from household size so the size-one limit applies. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + person2: + age: 42 + immigration_status: UNDOCUMENTED + spm_units: + spm_unit: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + output: + la_liheap_household_size: 1 + # floor(58,882 x 0.52) = floor(30,618.64) + la_liheap_income_limit: 30_618 + +- name: Case 2, a four-person household uses the published 58,882 limit. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + person2: + age: 33 + person3: + age: 8 + person4: + age: 5 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 600 + households: + household: + members: [person1, person2, person3, person4] + state_code: LA + output: + # floor(58,882 x 1.00) + la_liheap_income_limit: 58_882 + +- name: Case 3, a ten-person household uses the published 84,790 limit. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: {age: 42} + person2: {age: 40} + person3: {age: 17} + person4: {age: 16} + person5: {age: 14} + person6: {age: 12} + person7: {age: 10} + person8: {age: 8} + person9: {age: 7} + person10: {age: 6} + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 600 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10] + state_code: LA + output: + # floor(58,882 x 1.44) = floor(84,790.08) + la_liheap_income_limit: 84_790 + +- name: Case 4, a fourteen-person household extends the federal size adjustment to 91,855. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: {age: 45} + person2: {age: 43} + person3: {age: 17} + person4: {age: 16} + person5: {age: 15} + person6: {age: 14} + person7: {age: 13} + person8: {age: 12} + person9: {age: 11} + person10: {age: 10} + person11: {age: 9} + person12: {age: 8} + person13: {age: 7} + person14: {age: 6} + spm_units: + spm_unit: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 900 + households: + household: + members: [person1, person2, person3, person4, person5, person6, person7, person8, person9, person10, person11, person12, person13, person14] + state_code: LA + output: + # floor(58,882 x 1.56) = floor(91,855.92) + la_liheap_income_limit: 91_855 + +- name: Case 5, a household of only undocumented members has size zero and no income limit. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + immigration_status: UNDOCUMENTED + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + output: + la_liheap_household_size: 0 + la_liheap_income_limit: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/income/la_liheap_countable_income.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/income/la_liheap_countable_income.yaml new file mode 100644 index 00000000000..3708c4dc6f1 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/income/la_liheap_countable_income.yaml @@ -0,0 +1,304 @@ +# Service Delivery Guide (rev. January 1, 2024) pages 29-30 and Appendix E pages 81-86: +# gross earned and unearned income, net self-employment, rental and gambling income, +# Social Security net of the Medicare deduction, FITAP counted; child support, +# capital gains, bank or retirement-account withdrawals and SNAP not counted. +# Only income of members 18 and older counts (page 29), except Social Security and +# SSI paid to minors (Appendix E page 85; FAQ A4). +# Wages of 15,080 are full-time work at the federal 7.25 minimum wage (2,080 hours), +# which Louisiana follows. Electricity of 1,740 is about the EIA 2024 Louisiana +# average residential bill of 145 a month. + +- name: Case 1, gross wages and business income count while business and rental losses are floored at zero. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 15_080 + self_employment_income: 3_000 + partnership_s_corp_income: -1_500 + rental_income: -1_800 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + output: + # 15,080 + 3,000 + max(-1,500, 0) + max(-1,800, 0) = 18,080 + la_liheap_countable_income: 18_080 + +- name: Case 2, a 17-year-old's wages are excluded and an 18-year-old's wages are counted. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + employment_income: 30_000 + person2: + age: 18 + is_in_k12_school: false + employment_income: 6_000 + person3: + age: 17 + is_in_k12_school: false + employment_income: 4_000 + spm_units: + spm_unit: + members: [person1, person2, person3] + tanf: 0 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2, person3] + state_code: LA + output: + # 30,000 + 6,000; the 17-year-old's 4,000 is excluded (Appendix E page 82) + la_liheap_countable_income: 36_000 + +- name: Case 3, an 18-year-old still enrolled in high school has wages excluded. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + employment_income: 30_000 + person2: + age: 18 + is_in_k12_school: true + employment_income: 4_000 + spm_units: + spm_unit: + members: [person1, person2] + tanf: 0 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + output: + # The 18-year-old student's 4,000 is excluded (Appendix E page 82) + la_liheap_countable_income: 30_000 + +- name: Case 4, a minor's Social Security benefits are counted. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 38 + employment_income: 15_080 + person2: + age: 10 + # Child survivor benefit of 1,000 a month. + social_security: 12_000 + spm_units: + spm_unit: + members: [person1, person2] + tanf: 0 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + output: + # 15,080 + 12,000 (benefits paid to minors, Appendix E page 85) + la_liheap_countable_income: 27_080 + +- name: Case 5, Social Security is counted net of the Medicare Part B premium and floors at zero for each person. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 67 + ssi: 0 + social_security: 24_000 + # 2026 standard Part B premium of 202.90 a month. + medicare_part_b_premium: 2_434.80 + pension_income: 6_000 + person2: + age: 66 + ssi: 0 + social_security: 1_800 + medicare_part_b_premium: 2_434.80 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: NATURAL_GAS + gas_expense: 600 + households: + household: + members: [person1, person2] + state_code: LA + output: + # (24,000 - 2,434.80) + 6,000 + max(1,800 - 2,434.80, 0) = 21,565.20 + 6,000 + 0 + la_liheap_countable_income: 27_565.20 + +- name: Case 6, net gambling winnings count and one member's excess losses do not offset income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 50 + employment_income: 20_000 + gambling_winnings: 2_000 + gambling_losses: 500 + person2: + age: 48 + gambling_winnings: 300 + gambling_losses: 1_000 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + output: + # 20,000 + max(2,000 - 500, 0) + max(300 - 1,000, 0) = 20,000 + 1,500 + 0 + la_liheap_countable_income: 21_500 + +- name: Case 7, child support, capital gains and retirement-account withdrawals are not counted. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + employment_income: 15_080 + child_support_received: 4_800 + long_term_capital_gains: 1_000 + taxable_ira_distributions: 2_000 + person2: + age: 8 + spm_units: + spm_unit: + members: [person1, person2] + tanf: 0 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + output: + # Only the 15,080 wages count (Service Delivery Guide page 30 exclusions) + la_liheap_countable_income: 15_080 + +- name: Case 8, FITAP cash assistance received by the household is counted. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + person2: + age: 7 + person3: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3] + # FITAP three-person flat grant of 484 a month. + tanf: 5_808 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2, person3] + state_code: LA + output: + # 484 x 12 = 5,808 + la_liheap_countable_income: 5_808 + +- name: Case 9, an undocumented member's income counts in full. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 15_080 + person2: + age: 42 + immigration_status: UNDOCUMENTED + employment_income: 20_000 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + output: + # 15,080 + 20,000 (Service Delivery Guide page 34) + la_liheap_countable_income: 35_080 + +- name: Case 10, SSI and regular contributions count as unearned income. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + is_disabled: true + # 2026 federal SSI benefit rate of 994 a month. + ssi: 11_928 + # Regular support of 100 a month from a relative. + financial_assistance: 1_200 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + output: + # 994 x 12 + 1,200 = 11,928 + 1,200 + la_liheap_countable_income: 13_128 + +- name: Case 11, a 16-year-old's interest and dividends are excluded while the minor's SSI is counted. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 42 + employment_income: 30_000 + person2: + age: 16 + is_disabled: true + # Child SSI of 500 a month. + ssi: 6_000 + interest_income: 1_000 + ordinary_dividend_income: 200 + spm_units: + spm_unit: + members: [person1, person2] + tanf: 0 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + output: + # 30,000 wages + 6,000 minor's SSI; the minor's 1,000 interest and 200 dividends are excluded + la_liheap_countable_income: 36_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/la_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/la_liheap.yaml new file mode 100644 index 00000000000..0e9cd84da19 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/la_liheap.yaml @@ -0,0 +1,364 @@ +# FFY2026 Heating and Cooling Benefit Matrix: energy burden (energy cost / income) +# bands of 9.9% and less, 10-17.9%, 18-24.9% and 25% and greater pay 200, 350, 500 +# and 650 for one to three members and 250, 400, 550 and 700 for four or more. +# One 100 supplement per household for a member 60 or older, disabled, or five or +# younger. Zero income receives the maximum for the size (Service Delivery Guide +# page 41). Wages of 15,080 are full-time work at the federal 7.25 minimum wage; +# electricity of 1,740 is about the EIA 2024 Louisiana average residential bill of +# 145 a month. + +- name: Case 1, burden just below 10 percent receives the lowest size-one award. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 18_000 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_799 + households: + household: + members: [person1] + state_code: LA + output: + # 1,799 / 18,000 = 0.0999 -> band 1, size 1 + la_liheap: 200 + +- name: Case 2, burden exactly 10 percent starts the second band and age 59 adds no supplement. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 59 + employment_income: 18_000 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_800 + households: + household: + members: [person1] + state_code: LA + output: + # 1,800 / 18,000 = 0.10 -> band 2, size 1 + la_liheap: 350 + +- name: Case 3, burden exactly 18 percent for three members starts the third band and a six-year-old adds no supplement. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 30 + employment_income: 20_000 + person2: + age: 6 + person3: + age: 9 + spm_units: + spm_unit: + members: [person1, person2, person3] + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 1_200 + pre_subsidy_electricity_expense: 2_400 + households: + household: + members: [person1, person2, person3] + state_code: LA + output: + # (1,200 + 2,400) / 20,000 = 0.18 -> band 3, sizes 1-3 + la_liheap: 500 + +- name: Case 4, burden exactly 18 percent for four members uses the larger-household amount. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 32 + employment_income: 20_000 + person2: + age: 31 + person3: + age: 7 + person4: + age: 10 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 1_200 + pre_subsidy_electricity_expense: 2_400 + households: + household: + members: [person1, person2, person3, person4] + state_code: LA + output: + # (1,200 + 2,400) / 20,000 = 0.18 -> band 3, sizes 4+ + la_liheap: 550 + +- name: Case 5, burden exactly 25 percent receives the top band. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + # Part-time work at 7.25 an hour. + employment_income: 8_000 + person2: + age: 50 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 2_000 + households: + household: + members: [person1, person2] + state_code: LA + output: + # 2,000 / 8,000 = 0.25 -> band 4, size 2 + la_liheap: 650 + +- name: Case 6, zero countable income from a business loss receives the size maximum. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 35 + self_employment_income: -3_000 + person2: + age: 34 + person3: + age: 8 + person4: + age: 12 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tanf: 0 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2, person3, person4] + state_code: LA + output: + # max(-3,000, 0) = 0 income -> band 4, sizes 4+ + la_liheap: 700 + +- name: Case 7, a 60-year-old receives the priority supplement. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + pension_income: 14_400 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + output: + # 1,740 / 14,400 = 0.1208 -> band 2, size 1: 350 + 100 + la_liheap: 450 + +- name: Case 8, a disabled SSI recipient receives the priority supplement. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 45 + is_disabled: true + # 2026 federal SSI benefit rate of 994 a month. + ssi: 11_928 + spm_units: + spm_unit: + members: [person1] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 2_400 + households: + household: + members: [person1] + state_code: LA + output: + la_liheap_household_size: 1 + # 994 x 12 SSI + la_liheap_countable_income: 11_928 + la_liheap_income_limit: 30_618 + # Unsubsidized: no allowance deduction + la_liheap_energy_cost: 2_400 + la_liheap_eligible: true + # 2,400 / 11,928 = 0.2012 -> band 3, size 1: 500 + 100 + la_liheap: 600 + +- name: Case 9, a five-year-old receives the priority supplement. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 28 + employment_income: 15_080 + person2: + age: 5 + spm_units: + spm_unit: + members: [person1, person2] + tanf: 0 + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + output: + # 1,740 / 15,080 = 0.1154 -> band 2, size 2: 350 + 100 + la_liheap: 450 + +- name: Case 10, an undocumented 65-year-old's wages count but add no member or supplement. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 15_080 + person2: + age: 65 + immigration_status: UNDOCUMENTED + employment_income: 4_000 + spm_units: + spm_unit: + members: [person1, person2] + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + output: + # 1,740 / (15,080 + 4,000) = 0.0912 -> band 1, size 1, no supplement + la_liheap: 200 + +- name: Case 11, several priority members add one supplement and reach the 800 maximum. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 62 + pension_income: 6_000 + person2: + age: 33 + is_disabled: true + ssi: 0 + person3: + age: 4 + person4: + age: 8 + spm_units: + spm_unit: + members: [person1, person2, person3, person4] + tanf: 0 + heating_type: NATURAL_GAS + gas_expense: 900 + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2, person3, person4] + state_code: LA + output: + # (900 + 1,740) / 6,000 = 0.44 -> band 4, sizes 4+: 700 + 100 once + la_liheap: 800 + +- name: Case 12, unsubsidized heat in rent with no separate energy bills receives the lowest band. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + heating_type: NATURAL_GAS + gas_expense: 0 + heat_expense_included_in_rent: true + households: + household: + members: [person1] + state_code: LA + output: + # 0 / 15,080 = 0 -> band 1, size 1 + la_liheap: 200 + +- name: Case 13, a subsidized household's utility allowance lowers its burden band. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + receives_housing_assistance: true + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 2_400 + households: + household: + members: [person1] + state_code: LA + # Section 8 utility allowance of 120 a month. + hud_utility_allowance: 1_440 + output: + la_liheap_household_size: 1 + la_liheap_countable_income: 15_080 + la_liheap_income_limit: 30_618 + # 2,400 - 1,440 allowance (subsidized, under 60) + la_liheap_energy_cost: 960 + la_liheap_eligible: true + # 960 / 15,080 = 0.0637 -> band 1 (2,400 alone would be band 2) + la_liheap: 200 + +- name: Case 14, a subsidized household whose utility allowance exceeds its bill receives nothing. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 15_080 + spm_units: + spm_unit: + members: [person1] + receives_housing_assistance: true + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_500 + households: + household: + members: [person1] + state_code: LA + hud_utility_allowance: 1_800 + output: + # 1,500 - 1,800 = -300 energy cost -> ineligible + la_liheap: 0 diff --git a/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/la_liheap_energy_cost.yaml b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/la_liheap_energy_cost.yaml new file mode 100644 index 00000000000..c9a3e90207a --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/states/la/lhc/liheap/la_liheap_energy_cost.yaml @@ -0,0 +1,129 @@ +# Service Delivery Guide (rev. January 1, 2024) pages 37-40: residential energy bills +# from every vendor are added; sewer and water fees are excluded; a subsidized +# household subtracts its utility allowance (vendor costs - utility allowance = TEC), +# except applicants 60 or older. Electricity of 1,740 is about the EIA 2024 Louisiana +# average residential bill of 145 a month; gas of 600 is about 50 a month. + +- name: Case 1, energy bills from all vendors are added, water and sewer are excluded, and no allowance is deducted without housing assistance. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + spm_units: + spm_unit: + members: [person1] + receives_housing_assistance: false + heating_type: NATURAL_GAS + gas_expense: 600 + pre_subsidy_electricity_expense: 1_740 + # Firewood for a fireplace. + wood_expense: 200 + water_expense: 480 + sewage_expense: 360 + households: + household: + members: [person1] + state_code: LA + is_in_public_housing: false + # The local schedule amount, which is not deducted without housing assistance. + hud_utility_allowance: 1_200 + output: + # 600 + 1,740 + 200 = 2,540 + la_liheap_energy_cost: 2_540 + +- name: Case 2, a subsidized household with a 59-year-old has the utility allowance deducted. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 59 + spm_units: + spm_unit: + members: [person1] + receives_housing_assistance: true + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1] + state_code: LA + # Section 8 utility allowance of 100 a month. + hud_utility_allowance: 1_200 + output: + # 1,740 - 1,200 = 540 + la_liheap_energy_cost: 540 + +- name: Case 3, a public housing household whose allowance exceeds its bill has a negative energy cost. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + spm_units: + spm_unit: + members: [person1] + receives_housing_assistance: false + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_500 + households: + household: + members: [person1] + state_code: LA + is_in_public_housing: true + hud_utility_allowance: 1_800 + output: + # 1,500 - 1,800 = -300 + la_liheap_energy_cost: -300 + +- name: Case 4, a subsidized household with a 60-year-old member keeps the full bill. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 60 + person2: + age: 35 + spm_units: + spm_unit: + members: [person1, person2] + receives_housing_assistance: true + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + hud_utility_allowance: 1_200 + output: + # Applicants 60 or older are exempt: no deduction + la_liheap_energy_cost: 1_740 + +- name: Case 5, an undocumented 65-year-old does not exempt the household from the deduction. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + person2: + age: 65 + immigration_status: UNDOCUMENTED + spm_units: + spm_unit: + members: [person1, person2] + receives_housing_assistance: true + heating_type: ELECTRICITY + pre_subsidy_electricity_expense: 1_740 + households: + household: + members: [person1, person2] + state_code: LA + hud_utility_allowance: 1_200 + output: + # Only counted members qualify for the exemption: 1,740 - 1,200 = 540 + la_liheap_energy_cost: 540 diff --git a/policyengine_us/variables/gov/states/la/lhc/liheap/eligibility/la_liheap_eligible.py b/policyengine_us/variables/gov/states/la/lhc/liheap/eligibility/la_liheap_eligible.py new file mode 100644 index 00000000000..58f9d8d1421 --- /dev/null +++ b/policyengine_us/variables/gov/states/la/lhc/liheap/eligibility/la_liheap_eligible.py @@ -0,0 +1,65 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.tax_unit_fpg import fpg + + +class la_liheap_eligible(Variable): + value_type = bool + entity = SPMUnit + definition_period = YEAR + label = "Louisiana LIHEAP regular heating eligibility" + defined_for = StateCode.LA + reference = ( + # PDF pages 33, 35, 40 + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=33", + # PDF pages 39-41, 46-47 + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=39", + # PDF pages 9-10 + "https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=9", + "https://www.law.cornell.edu/uscode/text/42/8624#b_2_B", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.la.lhc.liheap.eligibility + p_hhs = parameters(period).gov.hhs.liheap + size = spm_unit("la_liheap_household_size", period) + income = spm_unit("la_liheap_countable_income", period) + limit = spm_unit("la_liheap_income_limit", period) + # 42 U.S.C. 8624(b)(2)(B) bars excluding a household on income below 110% + # of the poverty guideline. The 60% SMI limit falls below that floor from + # household size 14 in FY2026 (91,855 against 95,865). + state_group = spm_unit.household("state_group_str", period) + guideline = fpg(size, state_group, period, parameters, year_lag=p.fpg_year_lag) + floor = np.round(guideline * p_hhs.fpg_floor, 2) + income_eligible = (income <= limit) | (income < floor) + # Vulnerability: responsibility for a heating bill or heat included in + # the rent. + heat_in_rent = spm_unit("heat_expense_included_in_rent", period) + responsible = spm_unit("has_heating_expense", period) | heat_in_rent + heating_type = spm_unit("heating_type", period) + types = heating_type.possible_values + # The matrix has no fuel column, so an unspecified fuel qualifies when + # heat is included in the rent. + fuel_qualifies = (heating_type != types.NONE) & ( + heat_in_rent | (heating_type != types.UNSPECIFIED) + ) + # Subsidized households need a positive total energy cost: a utility + # allowance greater than the bill makes them ineligible, and an + # allowance equal to the bill leaves no energy burden. The guide's + # vulnerable subsidized tenant has an allowance "less" than the total + # energy cost (Section 3.6 E.1) and must show an energy burden + # (Section 4.1 C.1). + # Heat included in unsubsidized rent qualifies without a separately + # billed cost; the landlord-stated heating cost has no input. + subsidized = spm_unit("receives_housing_assistance", period) | ( + spm_unit.household("is_in_public_housing", period) + ) + energy_cost_eligible = ~subsidized | ( + spm_unit("la_liheap_energy_cost", period) > 0 + ) + return ( + (size > 0) + & income_eligible + & responsible + & fuel_qualifies + & energy_cost_eligible + ) diff --git a/policyengine_us/variables/gov/states/la/lhc/liheap/eligibility/la_liheap_income_limit.py b/policyengine_us/variables/gov/states/la/lhc/liheap/eligibility/la_liheap_income_limit.py new file mode 100644 index 00000000000..7e59342c7fe --- /dev/null +++ b/policyengine_us/variables/gov/states/la/lhc/liheap/eligibility/la_liheap_income_limit.py @@ -0,0 +1,26 @@ +from policyengine_us.model_api import * +from policyengine_us.variables.gov.hhs.hhs_smi import liheap_smi_limit + + +class la_liheap_income_limit(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Louisiana LIHEAP income limit" + defined_for = StateCode.LA + reference = ( + "https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=9", + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Notice%20LHP-2025-01%20-%20LIHEAP%20Income%20Eligibility%20Limits%20for%20FFY2026%20-%20LOUISIANA.pdf", + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=29", + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=34", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.la.lhc.liheap.eligibility + size = spm_unit("la_liheap_household_size", period) + state = spm_unit.household("state_code_str", period) + # The HHS floor order reproduces all ten FFY2026 notice rows. Sizes above + # 10 follow the federal size factors without a published Louisiana row. + limit = liheap_smi_limit(size, state, p.smi_rate, period, parameters) + return where(size > 0, limit, 0) diff --git a/policyengine_us/variables/gov/states/la/lhc/liheap/income/la_liheap_countable_income.py b/policyengine_us/variables/gov/states/la/lhc/liheap/income/la_liheap_countable_income.py new file mode 100644 index 00000000000..dd9f690f702 --- /dev/null +++ b/policyengine_us/variables/gov/states/la/lhc/liheap/income/la_liheap_countable_income.py @@ -0,0 +1,68 @@ +from policyengine_us.model_api import * + + +class la_liheap_countable_income(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Louisiana LIHEAP countable income" + defined_for = StateCode.LA + reference = ( + # PDF pages 29-30, 82-85 + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=29", + # PDF pages 34-36, 89-92 + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=34", + # PDF pages 5-7 + "https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=5", + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20Frequently%20Asked%20Questions%20(FAQs)%20-%202%2011%2022.pdf#page=2", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.la.lhc.liheap.income + person = spm_unit.members + # Annual inputs approximate the monthly income of the 30 days before + # application. The guide counts "Any income of a household member age + # 18 and older"; earned income also excludes members still enrolled in + # high school. + adult = person("age", period) >= p.adult_age + earned_counted = adult & ~person("is_in_k12_school", period) + # The guide counts gross income unless a source is listed as net, so + # each source is floored at zero and a loss in one source cannot offset + # another. + earned = 0 + for source in p.sources.earned: + earned = earned + max_(person(source, period), 0) + unearned = 0 + for source in p.sources.unearned: + unearned = unearned + max_(person(source, period), 0) + # Appendix E (Lump Sum rows) counts net gambling and lottery winnings and + # excludes other non-recurring lump sums. FY2026 plan Section 1.9 checks + # one-time lump-sum payments generally; the guide is followed. + gambling = max_( + person("gambling_winnings", period) - person("gambling_losses", period), + 0, + ) + # Appendix E (Social Security Benefits row) counts Social Security + # benefits, including SSI, "paid to minors", and FAQ A4 counts the + # Social Security a parent receives for a minor child, so both count + # for every member. Other benefits paid for minors are not counted. The + # guide counts "Net Social Security Administration (SSA) benefits" and + # FY2026 plan Section 1.9 counts them excluding the Medicare deduction, + # so the Part B premium the person pays is subtracted. + social_security = max_( + person("social_security", period) + - person("medicare_part_b_premium", period), + 0, + ) + ssi = person("ssi", period, options=[ADD]) + # Undocumented members keep all their income. FITAP is counted once at + # the SPM level: the take-up-gated tanf total includes la_fitap, which + # alone would count a grant a nonrecipient could get. + person_income = ( + earned * earned_counted + + (unearned + gambling) * adult + + social_security + + ssi + ) + return spm_unit.sum(person_income) + spm_unit("tanf", period) diff --git a/policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap.py b/policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap.py new file mode 100644 index 00000000000..677ffd1dc82 --- /dev/null +++ b/policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap.py @@ -0,0 +1,62 @@ +from policyengine_us.model_api import * + + +class la_liheap(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Louisiana LIHEAP regular heating assistance" + documentation = ( + "Louisiana's single regular heating-season award from the FFY2026 " + "Heating and Cooling Benefit Matrix: an amount by energy burden, on a " + "total-energy-cost basis, and household size, plus one priority group " + "supplement. Verified for FY2026; earlier and later years are " + "unverified estimates through parameter backfilling. The summer " + "cooling cycle, crisis assistance and weatherization are out of scope." + ) + defined_for = "la_liheap_eligible" + reference = ( + "https://liheapch.acf.gov/docs/2026/benefits-matricies/LA_BenefitMatrix_Heat-Cool_2026.pdf", + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=41", + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=48", + "https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=10", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.la.lhc.liheap + income = spm_unit("la_liheap_countable_income", period) + # NOTE: the formula also runs for ineligible units, whose energy cost can + # be negative; the floor keeps their burden band inside the matrix. + energy_cost = max_(spm_unit("la_liheap_energy_cost", period), 0) + # Annual cost over annual income stands in for the application-month + # bill over 30-day income. Heat included in unsubsidized rent counts + # only separately billed energy, so its band is a lower bound. + has_income = income > 0 + burden = np.divide( + energy_cost, + income, + out=np.zeros_like(energy_cost), + where=has_income, + ) + burden_band = p.payment.burden_band + # Households with zero income receive the maximum benefit for their + # size, the top burden band. + band = where(has_income, burden_band.calc(burden), burden_band.amounts[-1]) + size = spm_unit("la_liheap_household_size", period) + size_group = p.payment.size_group.calc(size) + base = p.payment.amount[band][size_group] + person = spm_unit.members + age = person("age", period) + priority_group = ( + (age >= p.elderly_age) + | person("is_disabled", period) + | (age < p.payment.young_child_max_age + 1) + ) + priority_member = person("is_citizen_or_legal_immigrant", period) & ( + priority_group + ) + supplement = spm_unit.any(priority_member) * p.payment.priority_supplement + # One award covers the heating season, with no bill cap. Supplemental + # heating payments depend on available funds and are not modeled. + return base + supplement diff --git a/policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap_energy_cost.py b/policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap_energy_cost.py new file mode 100644 index 00000000000..8b8b5e902cf --- /dev/null +++ b/policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap_energy_cost.py @@ -0,0 +1,41 @@ +from policyengine_us.model_api import * + + +class la_liheap_energy_cost(Variable): + value_type = float + entity = SPMUnit + definition_period = YEAR + unit = USD + label = "Louisiana LIHEAP total energy cost" + documentation = ( + "Annual residential energy bills from all vendors, less the HUD utility " + "allowance for subsidized households without a counted elderly member. " + "Negative when the allowance exceeds the bills." + ) + defined_for = StateCode.LA + reference = ( + # PDF pages 37-40 + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=37", + "https://liheapch.acf.gov/docs/2026/state-plans/LA_Plan_2026.pdf#page=9", + # PDF pages 43-47 + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=43", + ) + + def formula(spm_unit, period, parameters): + p = parameters(period).gov.states.la.lhc.liheap + bills = add(spm_unit, period, p.payment.energy_cost_sources) + subsidized = spm_unit("receives_housing_assistance", period) | ( + spm_unit.household("is_in_public_housing", period) + ) + person = spm_unit.members + elderly = spm_unit.any( + person("is_citizen_or_legal_immigrant", period) + & (person("age", period) >= p.elderly_age) + ) + # Total energy cost = vendor energy costs - utility allowance. The + # shared hud_utility_allowance has no Louisiana schedule, so the + # allowance is zero unless supplied. A supplied allowance should cover + # only the heating and cooling utilities (April 2026 guide, Section + # 4.1 C.1), not water, sewer or trash. + allowance = spm_unit.household("hud_utility_allowance", period) + return where(subsidized & ~elderly, bills - allowance, bills) diff --git a/policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap_household_size.py b/policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap_household_size.py new file mode 100644 index 00000000000..5ff5582fdf3 --- /dev/null +++ b/policyengine_us/variables/gov/states/la/lhc/liheap/la_liheap_household_size.py @@ -0,0 +1,22 @@ +from policyengine_us.model_api import * + + +class la_liheap_household_size(Variable): + value_type = int + entity = SPMUnit + definition_period = YEAR + label = "Louisiana LIHEAP household size" + defined_for = StateCode.LA + reference = ( + # PDF pages 33-34 + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20REVISED%20January%201_%202024.pdf#page=33", + # PDF pages 40-41 + "https://www.lhc.la.gov/hubfs/Document%20Libraries/Energy%20Assistance/Louisiana%20LIHEAP%20Service%20Delivery%20Guide%20-%20FINAL%20-%20Effective%20April%201%2c%202026.pdf#page=40", + ) + + # Citizens and qualified noncitizens count in household size. Undocumented + # members are excluded from size, but their income counts in full in + # la_liheap_countable_income. SPM membership approximates the LIHEAP + # household; Social Security number verification and the member + # exclusions of the April 2026 guide have no inputs. + adds = ["is_citizen_or_legal_immigrant"]