Add translation for write failures in nibe_heatpump (#148352)

This commit is contained in:
Joakim Plate 2025-07-07 18:48:34 +02:00 committed by GitHub
parent 6396f54e0d
commit 5c4f166f6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 112 additions and 2 deletions

View File

@ -10,12 +10,19 @@ from typing import Any
from nibe.coil import Coil, CoilData from nibe.coil import Coil, CoilData
from nibe.connection import Connection from nibe.connection import Connection
from nibe.exceptions import CoilNotFoundException, ReadException from nibe.exceptions import (
CoilNotFoundException,
ReadException,
WriteDeniedException,
WriteException,
WriteTimeoutException,
)
from nibe.heatpump import HeatPump, Series from nibe.heatpump import HeatPump, Series
from propcache.api import cached_property from propcache.api import cached_property
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -134,7 +141,36 @@ class CoilCoordinator(ContextCoordinator[dict[int, CoilData], int]):
async def async_write_coil(self, coil: Coil, value: float | str) -> None: async def async_write_coil(self, coil: Coil, value: float | str) -> None:
"""Write coil and update state.""" """Write coil and update state."""
data = CoilData(coil, value) data = CoilData(coil, value)
await self.connection.write_coil(data) try:
await self.connection.write_coil(data)
except WriteDeniedException as e:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="write_denied",
translation_placeholders={
"address": str(coil.address),
"value": str(value),
},
) from e
except WriteTimeoutException as e:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="write_timeout",
translation_placeholders={
"address": str(coil.address),
},
) from e
except WriteException as e:
LOGGER.debug("Failed to write", exc_info=True)
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="write_failed",
translation_placeholders={
"address": str(coil.address),
"value": str(value),
"error": str(e),
},
) from e
self.data[coil.address] = data self.data[coil.address] = data

View File

@ -45,5 +45,16 @@
"unknown": "[%key:common::config_flow::error::unknown%]", "unknown": "[%key:common::config_flow::error::unknown%]",
"url": "The specified URL is not well formed nor supported" "url": "The specified URL is not well formed nor supported"
} }
},
"exceptions": {
"write_denied": {
"message": "Writing of coil {address} with value `{value}` was denied"
},
"write_timeout": {
"message": "Timeout while writing coil {address}"
},
"write_failed": {
"message": "Writing of coil {address} with value `{value}` failed with error `{error}`"
}
} }
} }

View File

@ -4,6 +4,7 @@ from typing import Any
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, patch
from nibe.coil import CoilData from nibe.coil import CoilData
from nibe.exceptions import WriteDeniedException, WriteException, WriteTimeoutException
from nibe.heatpump import Model from nibe.heatpump import Model
import pytest import pytest
from syrupy.assertion import SnapshotAssertion from syrupy.assertion import SnapshotAssertion
@ -15,6 +16,7 @@ from homeassistant.components.number import (
) )
from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from . import async_add_model from . import async_add_model
@ -108,3 +110,64 @@ async def test_set_value(
assert isinstance(coil, CoilData) assert isinstance(coil, CoilData)
assert coil.coil.address == address assert coil.coil.address == address
assert coil.value == value assert coil.value == value
@pytest.mark.parametrize(
("exception", "translation_key", "translation_placeholders"),
[
(
WriteDeniedException("denied"),
"write_denied",
{"address": "47398", "value": "25.0"},
),
(
WriteTimeoutException("timeout writing"),
"write_timeout",
{"address": "47398"},
),
(
WriteException("failed"),
"write_failed",
{
"address": "47398",
"value": "25.0",
"error": "failed",
},
),
],
)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_set_value_fail(
hass: HomeAssistant,
mock_connection: AsyncMock,
exception: Exception,
translation_key: str,
translation_placeholders: dict[str, Any],
coils: dict[int, Any],
) -> None:
"""Test setting of value."""
value = 25
model = Model.F1155
address = 47398
entity_id = "number.room_sensor_setpoint_s1_47398"
coils[address] = 0
await async_add_model(hass, model)
await hass.async_block_till_done()
assert hass.states.get(entity_id)
mock_connection.write_coil.side_effect = exception
# Write value
with pytest.raises(HomeAssistantError) as exc_info:
await hass.services.async_call(
PLATFORM_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: entity_id, ATTR_VALUE: value},
blocking=True,
)
assert exc_info.value.translation_domain == "nibe_heatpump"
assert exc_info.value.translation_key == translation_key
assert exc_info.value.translation_placeholders == translation_placeholders