mirror of
https://github.com/home-assistant/core.git
synced 2026-10-07 06:50:41 -04:00
Keep Sofar diagnostics downloadable when the inverter is unreachable (#183218)
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
from dataclasses import asdict
|
||||
from typing import Any
|
||||
|
||||
from modbus_connection import ModbusError
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
@@ -19,8 +21,13 @@ async def async_get_config_entry_diagnostics(
|
||||
"""Return diagnostics for a config entry."""
|
||||
runtime_data = entry.runtime_data
|
||||
device = runtime_data.readings.device
|
||||
raw = await device.async_read_raw()
|
||||
if (holding := raw.get("holding")) is not None:
|
||||
raw = masks = read_error = None
|
||||
try:
|
||||
raw = await device.async_read_raw()
|
||||
masks = await device.async_read_masks()
|
||||
except ModbusError as err:
|
||||
read_error = type(err).__name__
|
||||
if raw is not None and (holding := raw.get("holding")) is not None:
|
||||
for address in _SERIAL_NUMBER_REGISTERS:
|
||||
holding.pop(address, None)
|
||||
|
||||
@@ -32,11 +39,12 @@ async def async_get_config_entry_diagnostics(
|
||||
"readings_components": device.readings_components,
|
||||
"settings_components": device.settings_components,
|
||||
"active_faults": sorted(fault.key for fault in device.state.active_faults),
|
||||
"address_masks": await device.async_read_masks(),
|
||||
"address_masks": masks,
|
||||
"link": {
|
||||
"tuning": asdict(runtime_data.tuner.tuning),
|
||||
"stats": asdict(runtime_data.link.stats),
|
||||
},
|
||||
"read_error": read_error,
|
||||
"raw": raw,
|
||||
},
|
||||
TO_REDACT,
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
'4358': 0,
|
||||
}),
|
||||
}),
|
||||
'read_error': None,
|
||||
'readings_components': list([
|
||||
'state',
|
||||
'grid',
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from modbus_connection import ModbusConnectionError, ModbusError, ModbusTimeoutError
|
||||
from modbus_connection.mock import MockModbusConnection
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
from syrupy.matchers import path_type
|
||||
|
||||
@@ -83,3 +85,33 @@ async def test_diagnostics_decodes_address_masks(
|
||||
diag = await get_diagnostics_for_config_entry(hass, hass_client, init_integration)
|
||||
|
||||
assert diag["address_masks"]["1024"] == 0x0001000200030004
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("error", "error_name"),
|
||||
[
|
||||
pytest.param(ModbusTimeoutError("silent"), "ModbusTimeoutError", id="timeout"),
|
||||
pytest.param(
|
||||
ModbusConnectionError("gone"), "ModbusConnectionError", id="link_lost"
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_diagnostics_inverter_unreachable(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_connection: MockModbusConnection,
|
||||
init_integration: MockConfigEntry,
|
||||
error: ModbusError,
|
||||
error_name: str,
|
||||
) -> None:
|
||||
"""Test diagnostics still download when the inverter stops answering."""
|
||||
unit = mock_connection.for_unit(1)
|
||||
unit.fail_requests(error)
|
||||
unit.read_events.clear()
|
||||
|
||||
diag = await get_diagnostics_for_config_entry(hass, hass_client, init_integration)
|
||||
|
||||
assert diag["read_error"] == error_name
|
||||
assert diag["raw"] is None
|
||||
assert diag["address_masks"] is None
|
||||
assert len(unit.read_events) == 1
|
||||
|
||||
Reference in New Issue
Block a user