diff --git a/custom_components/givenergy_local/givenergy_modbus/exceptions.py b/custom_components/givenergy_local/givenergy_modbus/exceptions.py index dcf6eb5..8d31e29 100644 --- a/custom_components/givenergy_local/givenergy_modbus/exceptions.py +++ b/custom_components/givenergy_local/givenergy_modbus/exceptions.py @@ -28,3 +28,7 @@ def __init__(self, message: str, frame: bytes) -> None: class CommunicationError(ExceptionBase): """Exception to indicate a communication error.""" + + +class ConversionError(ExceptionBase): + """Exception to indicate an error converting register values.""" diff --git a/custom_components/givenergy_local/givenergy_modbus/model/register.py b/custom_components/givenergy_local/givenergy_modbus/model/register.py index 52d6fc7..8b64364 100644 --- a/custom_components/givenergy_local/givenergy_modbus/model/register.py +++ b/custom_components/givenergy_local/givenergy_modbus/model/register.py @@ -5,6 +5,9 @@ from typing import Any, Callable, Optional, Union from pydantic.utils import GetterDict +from custom_components.givenergy_local.givenergy_modbus.exceptions import ( + ConversionError, +) from custom_components.givenergy_local.givenergy_modbus.model import TimeSlot @@ -160,23 +163,28 @@ def get(self, key: str, default: Any = None) -> Any: if None in regs: return None - if r.pre_conv: - if isinstance(r.pre_conv, tuple): - args = regs + list(r.pre_conv[1:]) - val = r.pre_conv[0](*args) + try: + if r.pre_conv: + if isinstance(r.pre_conv, tuple): + args = regs + list(r.pre_conv[1:]) + val = r.pre_conv[0](*args) + else: + val = r.pre_conv(*regs) else: - val = r.pre_conv(*regs) - else: - val = regs + val = regs - if r.post_conv: - if isinstance(r.post_conv, tuple): - return r.post_conv[0](val, *r.post_conv[1:]) - else: - if not isinstance(r.post_conv, Callable): - pass - return r.post_conv(val) - return val + if r.post_conv: + if isinstance(r.post_conv, tuple): + return r.post_conv[0](val, *r.post_conv[1:]) + else: + if not isinstance(r.post_conv, Callable): + pass + return r.post_conv(val) + return val + except ValueError as err: + raise ConversionError( + f"Failed to convert {key} from {regs}: {err}" + ) from err @classmethod def to_fields(cls) -> dict[str, tuple[Any, None]]: