diff --git a/changelog.d/nv-liheap-cooling.fixed.md b/changelog.d/nv-liheap-cooling.fixed.md new file mode 100644 index 00000000000..d2b01e6e82b --- /dev/null +++ b/changelog.d/nv-liheap-cooling.fixed.md @@ -0,0 +1 @@ +Nevada LIHEAP Fixed Annual Credit now pays households without heating, including cooling-only households, and no longer requires a heating bill, assuming every household has an active energy account. diff --git a/policyengine_us/programs.yaml b/policyengine_us/programs.yaml index 0f74596fd68..a39817beef2 100644 --- a/policyengine_us/programs.yaml +++ b/policyengine_us/programs.yaml @@ -1314,7 +1314,7 @@ programs: variable: nv_liheap parameter_prefix: gov.states.nv.dwss.liheap verified_years: "2026-2027" - notes: SFY2026-SFY2027 Fixed Annual Credit, Nevada's single regular benefit toward primary heating and electric costs, with the $360 minimum and the capped benefit tables. Crisis assistance and weatherization are out of scope. + notes: SFY2026-SFY2027 Fixed Annual Credit, Nevada's single regular benefit toward primary heating and electric costs, with the $360 minimum and the capped benefit tables; it also covers cooling-only households, and every household is assumed to have an active energy account. Crisis assistance and weatherization are out of scope. - state: NY status: partial name: New York HEAP diff --git a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/liheap/eligibility/nv_liheap_eligible.yaml b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/liheap/eligibility/nv_liheap_eligible.yaml index fd6519bc7bb..c3e0f419e0c 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/liheap/eligibility/nv_liheap_eligible.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/liheap/eligibility/nv_liheap_eligible.yaml @@ -1,7 +1,8 @@ # Countable annual gross income must not exceed 150% of the poverty guideline (NRS -# 702.260(3); EAP Manual 701, 802; SFY2026 size-one limit 23,475). The household needs a -# home heating source and responsibility for energy costs: a heating bill, or heat in the -# rent (803 V.3); households in subsidized or public housing with all utilities in the +# 702.260(3); EAP Manual 701, 802; SFY2026 size-one limit 23,475). Every household is +# assumed to have the active Nevada energy account that Manual 500 requires, so any known +# heating fuel or NONE qualifies without a bill; an unspecified fuel qualifies only with +# heat in the rent. Households in subsidized or public housing with all utilities in the # rent are ineligible unless they have an energy burden (501 I, 503). Household size # counts citizens and qualified non-citizens outside the five-year bar only (302 C, # 502 A.I). Wages of 18,720 are 30 hours a week at the Nevada minimum wage of 12.00; gas @@ -50,7 +51,7 @@ output: nv_liheap_eligible: false -- name: Case 3, a home with no heating is ineligible. +- name: Case 3, a home with no heating is eligible. period: 2026 input: people: @@ -67,7 +68,9 @@ members: [person1] state_code: NV output: - nv_liheap_eligible: false + # Was false, now true: every household is assumed to have the active energy + # account (Manual 500), and NONE is a sent heating_type; 18,720 <= 23,475. + nv_liheap_eligible: true - name: Case 4, an unspecified heating fuel without heat in rent is ineligible even with reported heating costs. period: 2026 @@ -207,7 +210,7 @@ # Energy cost 0 + 1,320 > 0: an energy burden remains (501 I) nv_liheap_eligible: true -- name: Case 10, a gas-heated home with a zero gas bill and heat outside the rent is ineligible. +- name: Case 10, a gas-heated home with a zero gas bill and heat outside the rent is eligible. period: 2026 input: people: @@ -225,7 +228,9 @@ members: [person1] state_code: NV output: - nv_liheap_eligible: false + # Was false, now true: every household is assumed to have the active energy + # account (Manual 500), so no heating bill is required; 18,720 <= 23,475. + nv_liheap_eligible: true - name: Case 11, a household of only undocumented members with no income is ineligible. period: 2026 @@ -282,3 +287,39 @@ # 24,960 > 23,475 nv_liheap_eligible: false nv_liheap: 0 + +- name: Case 13, a home with no heating and all utilities in the rent is ineligible only in subsidized housing. + period: 2026 + input: + people: + person1: + age: 40 + employment_income: 18_720 + person2: + age: 40 + employment_income: 18_720 + spm_units: + spm_unit1: + members: [person1] + heating_type: NONE + receives_housing_assistance: true + pre_subsidy_electricity_expense: 0 + spm_unit2: + members: [person2] + heating_type: NONE + receives_housing_assistance: false + pre_subsidy_electricity_expense: 0 + households: + household1: + members: [person1] + state_code: NV + tenant_pays_utilities: false + household2: + members: [person2] + state_code: NV + tenant_pays_utilities: false + output: + # The tenant pays no utilities and has no energy burden. With rental + # assistance the household is ineligible (501 I); without it the credit + # pays the minimum (803 V.3). + nv_liheap_eligible: [false, true] diff --git a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/liheap/nv_liheap.yaml b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/liheap/nv_liheap.yaml index 56265312aa2..d097459ed9f 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/liheap/nv_liheap.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/nv/dwss/liheap/nv_liheap.yaml @@ -717,3 +717,80 @@ # Arizona: the cap lookup clips size 0 to the size 1 row (guideline # 15,650 - 5,500 = 10,150, income 0 -> band 1); the benefit is 0 outside Nevada nv_liheap: [1_588.224, 0] + +# A home without heating receives the FAC on its electric cost alone: heating_expense is 0 +# for NONE, so the energy cost is the electricity bill, and the standard cap table +# applies. Every household is assumed to have the active energy account (Manual 500), so +# no bill or cooling cost is required, and a FAC below 360 pays 360 (803 V.1-2). +# Electricity of 1,500 is 125 a month. + +- name: Case 26, a cooling-only household receives a FAC on its electricity bill. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 18_720 + spm_units: + spm_unit: + members: [person1] + heating_type: NONE + has_cooling_expense: true + pre_subsidy_electricity_expense: 1_500 + households: + household: + members: [person1] + state_code: NV + output: + nv_liheap_energy_cost: 1_500 + # 1,500 - 0.0181 x 18,720 = 1,500 - 338.832 = 1,161.168 + # 18,720 / 15,650 = 1.196 -> band 3; standard cap 1,280 + nv_liheap: 1_161.168 + +- name: Case 27, a home without heating and without energy bills receives the 360 minimum. + period: 2026 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 18_720 + spm_units: + spm_unit: + members: [person1] + heating_type: NONE + has_cooling_expense: false + pre_subsidy_electricity_expense: 0 + households: + household: + members: [person1] + state_code: NV + output: + nv_liheap_eligible: true + # 0 - 0.0181 x 18,720 = -338.832 < 360 -> 360 + nv_liheap: 360 + +- name: Case 28, a cooling-only household in SFY2027 uses the 1.48 percent burden and the 2026 guideline. + period: 2027 + absolute_error_margin: 0.01 + input: + people: + person1: + age: 40 + employment_income: 18_720 + spm_units: + spm_unit: + members: [person1] + heating_type: NONE + has_cooling_expense: true + pre_subsidy_electricity_expense: 1_500 + households: + household: + members: [person1] + state_code: NV + output: + # 18,720 <= 23,940 + # 1,500 - 0.0148 x 18,720 = 1,500 - 277.056 = 1,222.944 + # 18,720 / 15,960 = 1.173 -> band 3; standard cap 1,280 + nv_liheap: 1_222.944 diff --git a/policyengine_us/variables/gov/states/nv/dwss/liheap/eligibility/nv_liheap_eligible.py b/policyengine_us/variables/gov/states/nv/dwss/liheap/eligibility/nv_liheap_eligible.py index 5053db5c415..2a2424a0063 100644 --- a/policyengine_us/variables/gov/states/nv/dwss/liheap/eligibility/nv_liheap_eligible.py +++ b/policyengine_us/variables/gov/states/nv/dwss/liheap/eligibility/nv_liheap_eligible.py @@ -13,10 +13,10 @@ class nv_liheap_eligible(Variable): "https://dss.nv.gov/uploadedFiles/dwssnvgov/content/Energy/FY%202026%20EAP%20Manual%2008.2025%20ADA.pdf#page=31", # PDF pages 31, 34, 43, 60-61 "https://www.dss.nv.gov/contentassets/b3bcdb93ea2d4b3f8dc252451a34cbe4/2027-eap-state-manual--08.25.26-1.pdf#page=31", - # PDF pages 5, 8 - "https://liheapch.acf.gov/docs/2026/state-plans/NV_Plan_2026.pdf#page=5", - # PDF pages 5, 8 - "https://www.dss.nv.gov/contentassets/b3bcdb93ea2d4b3f8dc252451a34cbe4/fy-2027-low-income-home-energy-assistance-program-liheap-state-plan.pdf#page=5", + # PDF pages 4-5, 8 + "https://liheapch.acf.gov/docs/2026/state-plans/NV_Plan_2026.pdf#page=4", + # PDF pages 4-5, 8 + "https://www.dss.nv.gov/contentassets/b3bcdb93ea2d4b3f8dc252451a34cbe4/fy-2027-low-income-home-energy-assistance-program-liheap-state-plan.pdf#page=4", ) def formula(spm_unit, period, parameters): @@ -30,23 +30,28 @@ def formula(spm_unit, period, parameters): income_eligible = income <= limit heat_in_rent = spm_unit("heat_expense_included_in_rent", period) heating_type = spm_unit("heating_type", period) - types = heating_type.possible_values - # A home without heat has no heating cost. An unspecified fuel - # qualifies only when heat is included in the rent. - fuel_qualifies = (heating_type != types.NONE) & ( - heat_in_rent | (heating_type != types.UNSPECIFIED) + # heating_type is a required input: any known fuel or NONE qualifies, + # and an unspecified fuel qualifies only when heat is included in the + # rent. Every household is assumed to have the active Nevada energy + # account that Section 500 requires, so no heating bill, electricity + # bill or cooling cost is needed. A credit on low or no energy costs + # pays the minimum (Section 803 V). + heating_type_reported = heat_in_rent | ( + heating_type != heating_type.possible_values.UNSPECIFIED + ) + # Subsidized or public housing tenants whose utilities are all included + # in the rent qualify only with an energy burden, a separately billed + # energy cost (Sections 501 I, 503 and 803 V.3). Heat in the rent or a + # tenant who does not pay utilities marks utilities in the rent; a home + # without heating can only use the latter. The Section 42-only housing + # exception, roomers and boarders, master meters and solar vendor + # credits have no inputs. + utilities_in_rent = heat_in_rent | ~spm_unit.household( + "tenant_pays_utilities", period ) - # Heat included in unsubsidized rent qualifies even without a bill, - # and the minimum benefit then applies. Subsidized or public housing - # tenants whose heat is included in the rent qualify only with an - # energy burden, a separately billed energy cost. The Section 42-only - # housing exception, roomers and boarders, master meters and solar - # vendor credits have no inputs. subsidized = spm_unit("receives_housing_assistance", period) | ( spm_unit.household("is_in_public_housing", period) ) energy_burden = spm_unit("nv_liheap_energy_cost", period) > 0 - rent_responsible = ~subsidized | energy_burden - direct_responsible = spm_unit("has_heating_expense", period) - responsible = where(heat_in_rent, rent_responsible, direct_responsible) - return (size > 0) & income_eligible & fuel_qualifies & responsible + housing_eligible = ~(utilities_in_rent & subsidized) | energy_burden + return (size > 0) & income_eligible & heating_type_reported & housing_eligible