1
mirror of https://github.com/home-assistant/core synced 2024-08-31 05:57:13 +02:00
ha-core/homeassistant/components/ipp/sensor.py

211 lines
6.2 KiB
Python

"""Support for IPP sensors."""
from __future__ import annotations
from datetime import timedelta
from typing import Any, Callable
from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_LOCATION, DEVICE_CLASS_TIMESTAMP, PERCENTAGE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import Entity
from homeassistant.util.dt import utcnow
from . import IPPDataUpdateCoordinator, IPPEntity
from .const import (
ATTR_COMMAND_SET,
ATTR_INFO,
ATTR_MARKER_HIGH_LEVEL,
ATTR_MARKER_LOW_LEVEL,
ATTR_MARKER_TYPE,
ATTR_SERIAL,
ATTR_STATE_MESSAGE,
ATTR_STATE_REASON,
ATTR_URI_SUPPORTED,
DOMAIN,
)
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: Callable[[list[Entity], bool], None],
) -> None:
"""Set up IPP sensor based on a config entry."""
coordinator: IPPDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
# config flow sets this to either UUID, serial number or None
unique_id = entry.unique_id
if unique_id is None:
unique_id = entry.entry_id
sensors = []
sensors.append(IPPPrinterSensor(entry.entry_id, unique_id, coordinator))
sensors.append(IPPUptimeSensor(entry.entry_id, unique_id, coordinator))
for marker_index in range(len(coordinator.data.markers)):
sensors.append(
IPPMarkerSensor(entry.entry_id, unique_id, coordinator, marker_index)
)
async_add_entities(sensors, True)
class IPPSensor(IPPEntity, SensorEntity):
"""Defines an IPP sensor."""
def __init__(
self,
*,
coordinator: IPPDataUpdateCoordinator,
enabled_default: bool = True,
entry_id: str,
unique_id: str,
icon: str,
key: str,
name: str,
unit_of_measurement: str | None = None,
) -> None:
"""Initialize IPP sensor."""
self._unit_of_measurement = unit_of_measurement
self._key = key
self._unique_id = None
if unique_id is not None:
self._unique_id = f"{unique_id}_{key}"
super().__init__(
entry_id=entry_id,
device_id=unique_id,
coordinator=coordinator,
name=name,
icon=icon,
enabled_default=enabled_default,
)
@property
def unique_id(self) -> str:
"""Return the unique ID for this sensor."""
return self._unique_id
@property
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return self._unit_of_measurement
class IPPMarkerSensor(IPPSensor):
"""Defines an IPP marker sensor."""
def __init__(
self,
entry_id: str,
unique_id: str,
coordinator: IPPDataUpdateCoordinator,
marker_index: int,
) -> None:
"""Initialize IPP marker sensor."""
self.marker_index = marker_index
super().__init__(
coordinator=coordinator,
entry_id=entry_id,
unique_id=unique_id,
icon="mdi:water",
key=f"marker_{marker_index}",
name=f"{coordinator.data.info.name} {coordinator.data.markers[marker_index].name}",
unit_of_measurement=PERCENTAGE,
)
@property
def extra_state_attributes(self) -> dict[str, Any] | None:
"""Return the state attributes of the entity."""
return {
ATTR_MARKER_HIGH_LEVEL: self.coordinator.data.markers[
self.marker_index
].high_level,
ATTR_MARKER_LOW_LEVEL: self.coordinator.data.markers[
self.marker_index
].low_level,
ATTR_MARKER_TYPE: self.coordinator.data.markers[
self.marker_index
].marker_type,
}
@property
def state(self) -> int | None:
"""Return the state of the sensor."""
level = self.coordinator.data.markers[self.marker_index].level
if level >= 0:
return level
return None
class IPPPrinterSensor(IPPSensor):
"""Defines an IPP printer sensor."""
def __init__(
self, entry_id: str, unique_id: str, coordinator: IPPDataUpdateCoordinator
) -> None:
"""Initialize IPP printer sensor."""
super().__init__(
coordinator=coordinator,
entry_id=entry_id,
unique_id=unique_id,
icon="mdi:printer",
key="printer",
name=coordinator.data.info.name,
unit_of_measurement=None,
)
@property
def extra_state_attributes(self) -> dict[str, Any] | None:
"""Return the state attributes of the entity."""
return {
ATTR_INFO: self.coordinator.data.info.printer_info,
ATTR_SERIAL: self.coordinator.data.info.serial,
ATTR_LOCATION: self.coordinator.data.info.location,
ATTR_STATE_MESSAGE: self.coordinator.data.state.message,
ATTR_STATE_REASON: self.coordinator.data.state.reasons,
ATTR_COMMAND_SET: self.coordinator.data.info.command_set,
ATTR_URI_SUPPORTED: self.coordinator.data.info.printer_uri_supported,
}
@property
def state(self) -> str:
"""Return the state of the sensor."""
return self.coordinator.data.state.printer_state
class IPPUptimeSensor(IPPSensor):
"""Defines a IPP uptime sensor."""
def __init__(
self, entry_id: str, unique_id: str, coordinator: IPPDataUpdateCoordinator
) -> None:
"""Initialize IPP uptime sensor."""
super().__init__(
coordinator=coordinator,
enabled_default=False,
entry_id=entry_id,
unique_id=unique_id,
icon="mdi:clock-outline",
key="uptime",
name=f"{coordinator.data.info.name} Uptime",
)
@property
def state(self) -> str:
"""Return the state of the sensor."""
uptime = utcnow() - timedelta(seconds=self.coordinator.data.info.uptime)
return uptime.replace(microsecond=0).isoformat()
@property
def device_class(self) -> str | None:
"""Return the class of this sensor."""
return DEVICE_CLASS_TIMESTAMP