1
0
mirror of https://github.com/home-assistant/core.git synced 2026-07-05 13:45:32 +01:00

Raise repair issue for under-voltage events in Raspberry Pi power supply checker (#174127)

This commit is contained in:
Manu
2026-06-18 17:28:20 +02:00
committed by GitHub
parent 66716e94c6
commit 8f367a3f28
5 changed files with 123 additions and 3 deletions
@@ -15,6 +15,7 @@ from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.issue_registry import IssueSeverity, create_issue
from . import RpiPowerConfigEntry
from .const import DOMAIN
@@ -63,6 +64,15 @@ class RaspberryChargerBinarySensor(BinarySensorEntity):
if self._attr_is_on != value:
if value:
_LOGGER.warning(DESCRIPTION_UNDER_VOLTAGE)
create_issue(
self.hass,
DOMAIN,
"under_voltage_detected",
is_fixable=True,
is_persistent=True,
severity=IssueSeverity.CRITICAL,
translation_key="under_voltage_detected",
)
else:
_LOGGER.debug(DESCRIPTION_NORMALIZED)
self._attr_is_on = value
@@ -0,0 +1,34 @@
"""Repairs for Raspberry Pi Power Supply Checker."""
from homeassistant.components.repairs import RepairsFlow, RepairsFlowResult
from homeassistant.core import HomeAssistant
async def async_create_fix_flow(
hass: HomeAssistant,
issue_id: str,
data: dict[str, str | int | float | None] | None,
) -> RepairsFlow:
"""Create flow."""
return UnderVoltageRepairFlow()
class UnderVoltageRepairFlow(RepairsFlow):
"""Handler for issue fixing flow."""
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> RepairsFlowResult:
"""Handle the first step of a fix flow."""
return await self.async_step_confirm()
async def async_step_confirm(
self, user_input: dict[str, str] | None = None
) -> RepairsFlowResult:
"""Handle the confirm step of a fix flow."""
if user_input is not None:
return self.async_create_entry(data={})
return self.async_show_form(step_id="confirm")
@@ -21,5 +21,18 @@
"message": "Under-voltage monitoring is not supported on this device."
}
},
"issues": {
"under_voltage_detected": {
"fix_flow": {
"step": {
"confirm": {
"description": "Your device has reported a low-voltage condition. The Raspberry Pi monitors its power input and records an under-voltage event when the supply voltage drops below approximately 4.63V. This can lead to instability, unexpected reboots, poor performance, storage corruption, or unreliable operation of Home Assistant.\n\nCommon causes include:\n\n- A power supply that cannot provide sufficient current.\n- A low-quality or damaged USB power cable causing voltage drop.\n- High-demand USB devices connected to the system.\n- Loose power connections.\n\nTo resolve this issue:\n\n- Switch to a higher quality power supply and cable.\n- Disconnect unnecessary USB devices and check whether the warning stops.\n\nAfter correcting the power issue, monitor the system to ensure no additional under-voltage events are reported.",
"title": "[%key:component::rpi_power::issues::under_voltage_detected::title%]"
}
}
},
"title": "Under-voltage detected"
}
},
"title": "Raspberry Pi Power Supply Checker"
}
@@ -16,7 +16,7 @@ from homeassistant.components.rpi_power.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers import entity_registry as er, issue_registry as ir
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
@@ -44,16 +44,26 @@ async def _async_setup_component(hass: HomeAssistant, detected: bool) -> MagicMo
return mocked_under_voltage
async def test_new(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) -> None:
async def test_new(
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
issue_registry: ir.IssueRegistry,
) -> None:
"""Test new entry."""
await _async_setup_component(hass, False)
state = hass.states.get(ENTITY_ID)
assert state.state == STATE_OFF
assert not any(x.levelno == logging.WARNING for x in caplog.records)
assert not issue_registry.async_get_issue(
domain=DOMAIN,
issue_id="under_voltage_detected",
)
async def test_new_detected(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
issue_registry: ir.IssueRegistry,
) -> None:
"""Test new entry with under voltage detected."""
mocked_under_voltage = await _async_setup_component(hass, True)
@@ -81,6 +91,11 @@ async def test_new_detected(
DESCRIPTION_NORMALIZED,
) in caplog.record_tuples
assert issue_registry.async_get_issue(
domain=DOMAIN,
issue_id="under_voltage_detected",
)
async def test_setup(
hass: HomeAssistant,
@@ -0,0 +1,48 @@
"""Tests for rpi_power repairs."""
from homeassistant.components.rpi_power.const import DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers import issue_registry as ir
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry, patch
from tests.components.repairs import (
async_process_repairs_platforms,
process_repair_fix_flow,
start_repair_fix_flow,
)
from tests.typing import ClientSessionGenerator
async def test_repair_flow(
hass: HomeAssistant,
issue_registry: ir.IssueRegistry,
hass_client: ClientSessionGenerator,
) -> None:
"""Test repair flow."""
config_entry = MockConfigEntry(domain=DOMAIN)
config_entry.add_to_hass(hass)
with patch("homeassistant.components.rpi_power.new_under_voltage", get=True):
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert issue_registry.async_get_issue(
domain=DOMAIN,
issue_id="under_voltage_detected",
)
assert await async_setup_component(hass, "repairs", {})
await async_process_repairs_platforms(hass)
client = await hass_client()
result = await start_repair_fix_flow(client, DOMAIN, "under_voltage_detected")
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "confirm"
result = await process_repair_fix_flow(client, result["flow_id"], {})
assert result["type"] == FlowResultType.CREATE_ENTRY
assert issue_registry.async_get_issue(DOMAIN, "under_voltage_detected") is None