"""Support for 1-Wire entities.""" from __future__ import annotations from dataclasses import dataclass import logging from typing import Any from pyownet import protocol from homeassistant.helpers.entity import DeviceInfo, Entity, EntityDescription from homeassistant.helpers.typing import StateType from .const import READ_MODE_BOOL, READ_MODE_INT @dataclass class OneWireEntityDescription(EntityDescription): """Class describing OneWire entities.""" read_mode: str | None = None _LOGGER = logging.getLogger(__name__) class OneWireBaseEntity(Entity): """Implementation of a 1-Wire entity.""" entity_description: OneWireEntityDescription def __init__( self, description: OneWireEntityDescription, device_id: str, device_info: DeviceInfo, device_file: str, name: str, ) -> None: """Initialize the entity.""" self.entity_description = description self._attr_unique_id = f"/{device_id}/{description.key}" self._attr_device_info = device_info self._attr_name = name self._device_file = device_file self._state: StateType = None self._value_raw: float | None = None @property def extra_state_attributes(self) -> dict[str, Any] | None: """Return the state attributes of the entity.""" return { "device_file": self._device_file, "raw_value": self._value_raw, } class OneWireProxyEntity(OneWireBaseEntity): """Implementation of a 1-Wire entity connected through owserver.""" def __init__( self, description: OneWireEntityDescription, device_id: str, device_info: DeviceInfo, device_file: str, name: str, owproxy: protocol._Proxy, ) -> None: """Initialize the sensor.""" super().__init__( description=description, device_id=device_id, device_info=device_info, device_file=device_file, name=name, ) self._owproxy = owproxy def _read_value_ownet(self) -> str: """Read a value from the owserver.""" read_bytes: bytes = self._owproxy.read(self._device_file) return read_bytes.decode().lstrip() def _write_value_ownet(self, value: bytes) -> None: """Write a value to the owserver.""" self._owproxy.write(self._device_file, value) def update(self) -> None: """Get the latest data from the device.""" try: self._value_raw = float(self._read_value_ownet()) except protocol.Error as exc: _LOGGER.error("Owserver failure in read(), got: %s", exc) self._state = None else: if self.entity_description.read_mode == READ_MODE_INT: self._state = int(self._value_raw) elif self.entity_description.read_mode == READ_MODE_BOOL: self._state = int(self._value_raw) == 1 else: self._state = round(self._value_raw, 1)