1 """Support for the Brother service."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
7 from datetime
import datetime
10 from brother
import BrotherSensors
16 SensorEntityDescription,
27 from .
import BrotherConfigEntry, BrotherDataUpdateCoordinator
28 from .const
import DOMAIN
30 ATTR_COUNTER =
"counter"
31 ATTR_REMAINING_PAGES =
"remaining_pages"
33 _LOGGER = logging.getLogger(__name__)
36 @dataclass(frozen=True, kw_only=True)
38 """A class that describes sensor entities."""
40 value: Callable[[BrotherSensors], StateType | datetime]
43 SENSOR_TYPES: tuple[BrotherSensorEntityDescription, ...] = (
46 translation_key=
"status",
47 entity_category=EntityCategory.DIAGNOSTIC,
48 value=
lambda data: data.status,
52 translation_key=
"page_counter",
53 state_class=SensorStateClass.MEASUREMENT,
54 entity_category=EntityCategory.DIAGNOSTIC,
55 value=
lambda data: data.page_counter,
59 translation_key=
"bw_pages",
60 state_class=SensorStateClass.MEASUREMENT,
61 entity_category=EntityCategory.DIAGNOSTIC,
62 value=
lambda data: data.bw_counter,
66 translation_key=
"color_pages",
67 state_class=SensorStateClass.MEASUREMENT,
68 entity_category=EntityCategory.DIAGNOSTIC,
69 value=
lambda data: data.color_counter,
72 key=
"duplex_unit_pages_counter",
73 translation_key=
"duplex_unit_page_counter",
74 state_class=SensorStateClass.MEASUREMENT,
75 entity_category=EntityCategory.DIAGNOSTIC,
76 value=
lambda data: data.duplex_unit_pages_counter,
79 key=
"drum_remaining_life",
80 translation_key=
"drum_remaining_life",
81 native_unit_of_measurement=PERCENTAGE,
82 state_class=SensorStateClass.MEASUREMENT,
83 entity_category=EntityCategory.DIAGNOSTIC,
84 value=
lambda data: data.drum_remaining_life,
87 key=
"drum_remaining_pages",
88 translation_key=
"drum_remaining_pages",
89 state_class=SensorStateClass.MEASUREMENT,
90 entity_category=EntityCategory.DIAGNOSTIC,
91 value=
lambda data: data.drum_remaining_pages,
95 translation_key=
"drum_page_counter",
96 state_class=SensorStateClass.MEASUREMENT,
97 entity_category=EntityCategory.DIAGNOSTIC,
98 value=
lambda data: data.drum_counter,
101 key=
"black_drum_remaining_life",
102 translation_key=
"black_drum_remaining_life",
103 native_unit_of_measurement=PERCENTAGE,
104 state_class=SensorStateClass.MEASUREMENT,
105 entity_category=EntityCategory.DIAGNOSTIC,
106 value=
lambda data: data.black_drum_remaining_life,
109 key=
"black_drum_remaining_pages",
110 translation_key=
"black_drum_remaining_pages",
111 state_class=SensorStateClass.MEASUREMENT,
112 entity_category=EntityCategory.DIAGNOSTIC,
113 value=
lambda data: data.black_drum_remaining_pages,
116 key=
"black_drum_counter",
117 translation_key=
"black_drum_page_counter",
118 state_class=SensorStateClass.MEASUREMENT,
119 entity_category=EntityCategory.DIAGNOSTIC,
120 value=
lambda data: data.black_drum_counter,
123 key=
"cyan_drum_remaining_life",
124 translation_key=
"cyan_drum_remaining_life",
125 native_unit_of_measurement=PERCENTAGE,
126 state_class=SensorStateClass.MEASUREMENT,
127 entity_category=EntityCategory.DIAGNOSTIC,
128 value=
lambda data: data.cyan_drum_remaining_life,
131 key=
"cyan_drum_remaining_pages",
132 translation_key=
"cyan_drum_remaining_pages",
133 state_class=SensorStateClass.MEASUREMENT,
134 entity_category=EntityCategory.DIAGNOSTIC,
135 value=
lambda data: data.cyan_drum_remaining_pages,
138 key=
"cyan_drum_counter",
139 translation_key=
"cyan_drum_page_counter",
140 state_class=SensorStateClass.MEASUREMENT,
141 entity_category=EntityCategory.DIAGNOSTIC,
142 value=
lambda data: data.cyan_drum_counter,
145 key=
"magenta_drum_remaining_life",
146 translation_key=
"magenta_drum_remaining_life",
147 native_unit_of_measurement=PERCENTAGE,
148 state_class=SensorStateClass.MEASUREMENT,
149 entity_category=EntityCategory.DIAGNOSTIC,
150 value=
lambda data: data.magenta_drum_remaining_life,
153 key=
"magenta_drum_remaining_pages",
154 translation_key=
"magenta_drum_remaining_pages",
155 state_class=SensorStateClass.MEASUREMENT,
156 entity_category=EntityCategory.DIAGNOSTIC,
157 value=
lambda data: data.magenta_drum_remaining_pages,
160 key=
"magenta_drum_counter",
161 translation_key=
"magenta_drum_page_counter",
162 state_class=SensorStateClass.MEASUREMENT,
163 entity_category=EntityCategory.DIAGNOSTIC,
164 value=
lambda data: data.magenta_drum_counter,
167 key=
"yellow_drum_remaining_life",
168 translation_key=
"yellow_drum_remaining_life",
169 native_unit_of_measurement=PERCENTAGE,
170 state_class=SensorStateClass.MEASUREMENT,
171 entity_category=EntityCategory.DIAGNOSTIC,
172 value=
lambda data: data.yellow_drum_remaining_life,
175 key=
"yellow_drum_remaining_pages",
176 translation_key=
"yellow_drum_remaining_pages",
177 state_class=SensorStateClass.MEASUREMENT,
178 entity_category=EntityCategory.DIAGNOSTIC,
179 value=
lambda data: data.yellow_drum_remaining_pages,
182 key=
"yellow_drum_counter",
183 translation_key=
"yellow_drum_page_counter",
184 state_class=SensorStateClass.MEASUREMENT,
185 entity_category=EntityCategory.DIAGNOSTIC,
186 value=
lambda data: data.yellow_drum_counter,
189 key=
"belt_unit_remaining_life",
190 translation_key=
"belt_unit_remaining_life",
191 native_unit_of_measurement=PERCENTAGE,
192 state_class=SensorStateClass.MEASUREMENT,
193 entity_category=EntityCategory.DIAGNOSTIC,
194 value=
lambda data: data.belt_unit_remaining_life,
197 key=
"fuser_remaining_life",
198 translation_key=
"fuser_remaining_life",
199 native_unit_of_measurement=PERCENTAGE,
200 state_class=SensorStateClass.MEASUREMENT,
201 entity_category=EntityCategory.DIAGNOSTIC,
202 value=
lambda data: data.fuser_remaining_life,
205 key=
"laser_remaining_life",
206 translation_key=
"laser_remaining_life",
207 native_unit_of_measurement=PERCENTAGE,
208 state_class=SensorStateClass.MEASUREMENT,
209 entity_category=EntityCategory.DIAGNOSTIC,
210 value=
lambda data: data.laser_remaining_life,
213 key=
"pf_kit_1_remaining_life",
214 translation_key=
"pf_kit_1_remaining_life",
215 native_unit_of_measurement=PERCENTAGE,
216 state_class=SensorStateClass.MEASUREMENT,
217 entity_category=EntityCategory.DIAGNOSTIC,
218 value=
lambda data: data.pf_kit_1_remaining_life,
221 key=
"pf_kit_mp_remaining_life",
222 translation_key=
"pf_kit_mp_remaining_life",
223 native_unit_of_measurement=PERCENTAGE,
224 state_class=SensorStateClass.MEASUREMENT,
225 entity_category=EntityCategory.DIAGNOSTIC,
226 value=
lambda data: data.pf_kit_mp_remaining_life,
229 key=
"black_toner_remaining",
230 translation_key=
"black_toner_remaining",
231 native_unit_of_measurement=PERCENTAGE,
232 state_class=SensorStateClass.MEASUREMENT,
233 entity_category=EntityCategory.DIAGNOSTIC,
234 value=
lambda data: data.black_toner_remaining,
237 key=
"cyan_toner_remaining",
238 translation_key=
"cyan_toner_remaining",
239 native_unit_of_measurement=PERCENTAGE,
240 state_class=SensorStateClass.MEASUREMENT,
241 entity_category=EntityCategory.DIAGNOSTIC,
242 value=
lambda data: data.cyan_toner_remaining,
245 key=
"magenta_toner_remaining",
246 translation_key=
"magenta_toner_remaining",
247 native_unit_of_measurement=PERCENTAGE,
248 state_class=SensorStateClass.MEASUREMENT,
249 entity_category=EntityCategory.DIAGNOSTIC,
250 value=
lambda data: data.magenta_toner_remaining,
253 key=
"yellow_toner_remaining",
254 translation_key=
"yellow_toner_remaining",
255 native_unit_of_measurement=PERCENTAGE,
256 state_class=SensorStateClass.MEASUREMENT,
257 entity_category=EntityCategory.DIAGNOSTIC,
258 value=
lambda data: data.yellow_toner_remaining,
261 key=
"black_ink_remaining",
262 translation_key=
"black_ink_remaining",
263 native_unit_of_measurement=PERCENTAGE,
264 state_class=SensorStateClass.MEASUREMENT,
265 entity_category=EntityCategory.DIAGNOSTIC,
266 value=
lambda data: data.black_ink_remaining,
269 key=
"cyan_ink_remaining",
270 translation_key=
"cyan_ink_remaining",
271 native_unit_of_measurement=PERCENTAGE,
272 state_class=SensorStateClass.MEASUREMENT,
273 entity_category=EntityCategory.DIAGNOSTIC,
274 value=
lambda data: data.cyan_ink_remaining,
277 key=
"magenta_ink_remaining",
278 translation_key=
"magenta_ink_remaining",
279 native_unit_of_measurement=PERCENTAGE,
280 state_class=SensorStateClass.MEASUREMENT,
281 entity_category=EntityCategory.DIAGNOSTIC,
282 value=
lambda data: data.magenta_ink_remaining,
285 key=
"yellow_ink_remaining",
286 translation_key=
"yellow_ink_remaining",
287 native_unit_of_measurement=PERCENTAGE,
288 state_class=SensorStateClass.MEASUREMENT,
289 entity_category=EntityCategory.DIAGNOSTIC,
290 value=
lambda data: data.yellow_ink_remaining,
294 translation_key=
"last_restart",
295 entity_registry_enabled_default=
False,
296 device_class=SensorDeviceClass.TIMESTAMP,
297 entity_category=EntityCategory.DIAGNOSTIC,
298 value=
lambda data: data.uptime,
305 entry: BrotherConfigEntry,
306 async_add_entities: AddEntitiesCallback,
308 """Add Brother entities from a config_entry."""
309 coordinator = entry.runtime_data
312 entity_registry = er.async_get(hass)
313 old_unique_id = f
"{coordinator.brother.serial.lower()}_b/w_counter"
314 if entity_id := entity_registry.async_get_entity_id(
315 PLATFORM, DOMAIN, old_unique_id
317 new_unique_id = f
"{coordinator.brother.serial.lower()}_bw_counter"
319 "Migrating entity %s from old unique ID '%s' to new unique ID '%s'",
324 entity_registry.async_update_entity(entity_id, new_unique_id=new_unique_id)
328 for description
in SENSOR_TYPES
329 if description.value(coordinator.data)
is not None
334 CoordinatorEntity[BrotherDataUpdateCoordinator], SensorEntity
336 """Define an Brother Printer sensor."""
338 _attr_has_entity_name =
True
339 entity_description: BrotherSensorEntityDescription
343 coordinator: BrotherDataUpdateCoordinator,
344 description: BrotherSensorEntityDescription,
349 configuration_url=f
"http://{coordinator.brother.host}/",
350 identifiers={(DOMAIN, coordinator.brother.serial)},
351 connections={(CONNECTION_NETWORK_MAC, coordinator.brother.mac)},
352 serial_number=coordinator.brother.serial,
353 manufacturer=
"Brother",
354 model=coordinator.brother.model,
355 name=coordinator.brother.model,
356 sw_version=coordinator.brother.firmware,
359 self.
_attr_unique_id_attr_unique_id = f
"{coordinator.brother.serial.lower()}_{description.key}"
364 """Handle updated data from the coordinator."""
None __init__(self, BrotherDataUpdateCoordinator coordinator, BrotherSensorEntityDescription description)
None _handle_coordinator_update(self)
None async_write_ha_state(self)
None async_setup_entry(HomeAssistant hass, BrotherConfigEntry entry, AddEntitiesCallback async_add_entities)