424 lines
15 KiB
Python
424 lines
15 KiB
Python
"""Support for the Brother service."""
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Callable
|
|
from dataclasses import dataclass
|
|
from datetime import datetime
|
|
import logging
|
|
|
|
from brother import BrotherSensors
|
|
|
|
from homeassistant.components.sensor import (
|
|
DOMAIN as PLATFORM,
|
|
SensorDeviceClass,
|
|
SensorEntity,
|
|
SensorEntityDescription,
|
|
SensorStateClass,
|
|
)
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import CONF_HOST, PERCENTAGE
|
|
from homeassistant.core import HomeAssistant, callback
|
|
from homeassistant.helpers import entity_registry as er
|
|
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
from homeassistant.helpers.typing import StateType
|
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|
|
|
from . import BrotherDataUpdateCoordinator
|
|
from .const import DATA_CONFIG_ENTRY, DOMAIN
|
|
|
|
ATTR_COUNTER = "counter"
|
|
ATTR_REMAINING_PAGES = "remaining_pages"
|
|
|
|
UNIT_PAGES = "p"
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
@dataclass
|
|
class BrotherSensorRequiredKeysMixin:
|
|
"""Class for Brother entity required keys."""
|
|
|
|
value: Callable[[BrotherSensors], StateType | datetime]
|
|
|
|
|
|
@dataclass
|
|
class BrotherSensorEntityDescription(
|
|
SensorEntityDescription, BrotherSensorRequiredKeysMixin
|
|
):
|
|
"""A class that describes sensor entities."""
|
|
|
|
|
|
SENSOR_TYPES: tuple[BrotherSensorEntityDescription, ...] = (
|
|
BrotherSensorEntityDescription(
|
|
key="status",
|
|
icon="mdi:printer",
|
|
name="Status",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.status,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="page_counter",
|
|
icon="mdi:file-document-outline",
|
|
name="Page counter",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.page_counter,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="bw_counter",
|
|
icon="mdi:file-document-outline",
|
|
name="B/W counter",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.bw_counter,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="color_counter",
|
|
icon="mdi:file-document-outline",
|
|
name="Color counter",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.color_counter,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="duplex_unit_pages_counter",
|
|
icon="mdi:file-document-outline",
|
|
name="Duplex unit pages counter",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.duplex_unit_pages_counter,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="drum_remaining_life",
|
|
icon="mdi:chart-donut",
|
|
name="Drum remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.drum_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="drum_remaining_pages",
|
|
icon="mdi:chart-donut",
|
|
name="Drum remaining pages",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.drum_remaining_pages,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="drum_counter",
|
|
icon="mdi:chart-donut",
|
|
name="Drum counter",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.drum_counter,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="black_drum_remaining_life",
|
|
icon="mdi:chart-donut",
|
|
name="Black drum remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.black_drum_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="black_drum_remaining_pages",
|
|
icon="mdi:chart-donut",
|
|
name="Black drum remaining pages",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.black_drum_remaining_pages,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="black_drum_counter",
|
|
icon="mdi:chart-donut",
|
|
name="Black drum counter",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.black_drum_counter,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="cyan_drum_remaining_life",
|
|
icon="mdi:chart-donut",
|
|
name="Cyan drum remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.cyan_drum_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="cyan_drum_remaining_pages",
|
|
icon="mdi:chart-donut",
|
|
name="Cyan drum remaining pages",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.cyan_drum_remaining_pages,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="cyan_drum_counter",
|
|
icon="mdi:chart-donut",
|
|
name="Cyan drum counter",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.cyan_drum_counter,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="magenta_drum_remaining_life",
|
|
icon="mdi:chart-donut",
|
|
name="Magenta drum remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.magenta_drum_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="magenta_drum_remaining_pages",
|
|
icon="mdi:chart-donut",
|
|
name="Magenta drum remaining pages",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.magenta_drum_remaining_pages,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="magenta_drum_counter",
|
|
icon="mdi:chart-donut",
|
|
name="Magenta drum counter",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.magenta_drum_counter,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="yellow_drum_remaining_life",
|
|
icon="mdi:chart-donut",
|
|
name="Yellow drum remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.yellow_drum_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="yellow_drum_remaining_pages",
|
|
icon="mdi:chart-donut",
|
|
name="Yellow drum remaining pages",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.yellow_drum_remaining_pages,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="yellow_drum_counter",
|
|
icon="mdi:chart-donut",
|
|
name="Yellow drum counter",
|
|
native_unit_of_measurement=UNIT_PAGES,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.yellow_drum_counter,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="belt_unit_remaining_life",
|
|
icon="mdi:current-ac",
|
|
name="Belt unit remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.belt_unit_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="fuser_remaining_life",
|
|
icon="mdi:water-outline",
|
|
name="Fuser remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.fuser_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="laser_remaining_life",
|
|
icon="mdi:spotlight-beam",
|
|
name="Laser remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.laser_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="pf_kit_1_remaining_life",
|
|
icon="mdi:printer-3d",
|
|
name="PF Kit 1 remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.pf_kit_1_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="pf_kit_mp_remaining_life",
|
|
icon="mdi:printer-3d",
|
|
name="PF Kit MP remaining life",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.pf_kit_mp_remaining_life,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="black_toner_remaining",
|
|
icon="mdi:printer-3d-nozzle",
|
|
name="Black toner remaining",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.black_toner_remaining,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="cyan_toner_remaining",
|
|
icon="mdi:printer-3d-nozzle",
|
|
name="Cyan toner remaining",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.cyan_toner_remaining,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="magenta_toner_remaining",
|
|
icon="mdi:printer-3d-nozzle",
|
|
name="Magenta toner remaining",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.magenta_toner_remaining,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="yellow_toner_remaining",
|
|
icon="mdi:printer-3d-nozzle",
|
|
name="Yellow toner remaining",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.yellow_toner_remaining,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="black_ink_remaining",
|
|
icon="mdi:printer-3d-nozzle",
|
|
name="Black ink remaining",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.black_ink_remaining,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="cyan_ink_remaining",
|
|
icon="mdi:printer-3d-nozzle",
|
|
name="Cyan ink remaining",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.cyan_ink_remaining,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="magenta_ink_remaining",
|
|
icon="mdi:printer-3d-nozzle",
|
|
name="Magenta ink remaining",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.magenta_ink_remaining,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="yellow_ink_remaining",
|
|
icon="mdi:printer-3d-nozzle",
|
|
name="Yellow ink remaining",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.yellow_ink_remaining,
|
|
),
|
|
BrotherSensorEntityDescription(
|
|
key="uptime",
|
|
name="Uptime",
|
|
entity_registry_enabled_default=False,
|
|
device_class=SensorDeviceClass.TIMESTAMP,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
value=lambda data: data.uptime,
|
|
),
|
|
)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
|
) -> None:
|
|
"""Add Brother entities from a config_entry."""
|
|
coordinator = hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id]
|
|
|
|
# Due to the change of the attribute name of one sensor, it is necessary to migrate
|
|
# the unique_id to the new one.
|
|
entity_registry = er.async_get(hass)
|
|
old_unique_id = f"{coordinator.data.serial.lower()}_b/w_counter"
|
|
if entity_id := entity_registry.async_get_entity_id(
|
|
PLATFORM, DOMAIN, old_unique_id
|
|
):
|
|
new_unique_id = f"{coordinator.data.serial.lower()}_bw_counter"
|
|
_LOGGER.debug(
|
|
"Migrating entity %s from old unique ID '%s' to new unique ID '%s'",
|
|
entity_id,
|
|
old_unique_id,
|
|
new_unique_id,
|
|
)
|
|
entity_registry.async_update_entity(entity_id, new_unique_id=new_unique_id)
|
|
|
|
sensors = []
|
|
|
|
device_info = DeviceInfo(
|
|
configuration_url=f"http://{entry.data[CONF_HOST]}/",
|
|
identifiers={(DOMAIN, coordinator.data.serial)},
|
|
manufacturer="Brother",
|
|
model=coordinator.data.model,
|
|
name=coordinator.data.model,
|
|
sw_version=coordinator.data.firmware,
|
|
)
|
|
|
|
for description in SENSOR_TYPES:
|
|
if description.value(coordinator.data) is not None:
|
|
sensors.append(BrotherPrinterSensor(coordinator, description, device_info))
|
|
async_add_entities(sensors, False)
|
|
|
|
|
|
class BrotherPrinterSensor(
|
|
CoordinatorEntity[BrotherDataUpdateCoordinator], SensorEntity
|
|
):
|
|
"""Define an Brother Printer sensor."""
|
|
|
|
_attr_has_entity_name = True
|
|
entity_description: BrotherSensorEntityDescription
|
|
|
|
def __init__(
|
|
self,
|
|
coordinator: BrotherDataUpdateCoordinator,
|
|
description: BrotherSensorEntityDescription,
|
|
device_info: DeviceInfo,
|
|
) -> None:
|
|
"""Initialize."""
|
|
super().__init__(coordinator)
|
|
self._attr_device_info = device_info
|
|
self._attr_native_value = description.value(coordinator.data)
|
|
self._attr_unique_id = f"{coordinator.data.serial.lower()}_{description.key}"
|
|
self.entity_description = description
|
|
|
|
@callback
|
|
def _handle_coordinator_update(self) -> None:
|
|
"""Handle updated data from the coordinator."""
|
|
self._attr_native_value = self.entity_description.value(self.coordinator.data)
|
|
self.async_write_ha_state()
|