Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Samsung Printers with SyncThru web interface."""
2 
3 from __future__ import annotations
4 
5 from pysyncthru import SyncThru, SyncthruState
6 
7 from homeassistant.components.sensor import SensorEntity
8 from homeassistant.config_entries import ConfigEntry
9 from homeassistant.const import CONF_NAME, PERCENTAGE
10 from homeassistant.core import HomeAssistant
11 from homeassistant.helpers.device_registry import DeviceInfo
12 from homeassistant.helpers.entity_platform import AddEntitiesCallback
14  CoordinatorEntity,
15  DataUpdateCoordinator,
16 )
17 
18 from . import device_identifiers
19 from .const import DOMAIN
20 
21 COLORS = ["black", "cyan", "magenta", "yellow"]
22 DRUM_COLORS = COLORS
23 TONER_COLORS = COLORS
24 TRAYS = range(1, 6)
25 OUTPUT_TRAYS = range(6)
26 DEFAULT_MONITORED_CONDITIONS = []
27 DEFAULT_MONITORED_CONDITIONS.extend([f"toner_{key}" for key in TONER_COLORS])
28 DEFAULT_MONITORED_CONDITIONS.extend([f"drum_{key}" for key in DRUM_COLORS])
29 DEFAULT_MONITORED_CONDITIONS.extend([f"tray_{key}" for key in TRAYS])
30 DEFAULT_MONITORED_CONDITIONS.extend([f"output_tray_{key}" for key in OUTPUT_TRAYS])
31 
32 SYNCTHRU_STATE_HUMAN = {
33  SyncthruState.INVALID: "invalid",
34  SyncthruState.OFFLINE: "unreachable",
35  SyncthruState.NORMAL: "normal",
36  SyncthruState.UNKNOWN: "unknown",
37  SyncthruState.WARNING: "warning",
38  SyncthruState.TESTING: "testing",
39  SyncthruState.ERROR: "error",
40 }
41 
42 
44  hass: HomeAssistant,
45  config_entry: ConfigEntry,
46  async_add_entities: AddEntitiesCallback,
47 ) -> None:
48  """Set up from config entry."""
49 
50  coordinator: DataUpdateCoordinator[SyncThru] = hass.data[DOMAIN][
51  config_entry.entry_id
52  ]
53  printer: SyncThru = coordinator.data
54 
55  supp_toner = printer.toner_status(filter_supported=True)
56  supp_drum = printer.drum_status(filter_supported=True)
57  supp_tray = printer.input_tray_status(filter_supported=True)
58  supp_output_tray = printer.output_tray_status()
59 
60  name: str = config_entry.data[CONF_NAME]
61  entities: list[SyncThruSensor] = [
62  SyncThruMainSensor(coordinator, name),
63  SyncThruActiveAlertSensor(coordinator, name),
64  ]
65  entities.extend(SyncThruTonerSensor(coordinator, name, key) for key in supp_toner)
66  entities.extend(SyncThruDrumSensor(coordinator, name, key) for key in supp_drum)
67  entities.extend(
68  SyncThruInputTraySensor(coordinator, name, key) for key in supp_tray
69  )
70  entities.extend(
71  SyncThruOutputTraySensor(coordinator, name, int_key)
72  for int_key in supp_output_tray
73  )
74 
75  async_add_entities(entities)
76 
77 
78 class SyncThruSensor(CoordinatorEntity[DataUpdateCoordinator[SyncThru]], SensorEntity):
79  """Implementation of an abstract Samsung Printer sensor platform."""
80 
81  _attr_icon = "mdi:printer"
82 
83  def __init__(self, coordinator: DataUpdateCoordinator[SyncThru], name: str) -> None:
84  """Initialize the sensor."""
85  super().__init__(coordinator)
86  self.syncthrusyncthru = coordinator.data
87  self._attr_name_attr_name = name
88  self._id_suffix_id_suffix = ""
89 
90  @property
91  def unique_id(self):
92  """Return unique ID for the sensor."""
93  serial = self.syncthrusyncthru.serial_number()
94  return f"{serial}{self._id_suffix}" if serial else None
95 
96  @property
97  def device_info(self) -> DeviceInfo | None:
98  """Return device information."""
99  if (identifiers := device_identifiers(self.syncthrusyncthru)) is None:
100  return None
101  return DeviceInfo(
102  identifiers=identifiers,
103  )
104 
105 
107  """Implementation of the main sensor, conducting the actual polling.
108 
109  It also shows the detailed state and presents
110  the displayed current status message.
111  """
112 
113  _attr_entity_registry_enabled_default = False
114 
115  def __init__(self, coordinator: DataUpdateCoordinator[SyncThru], name: str) -> None:
116  """Initialize the sensor."""
117  super().__init__(coordinator, name)
118  self._id_suffix_id_suffix_id_suffix = "_main"
119 
120  @property
121  def native_value(self):
122  """Set state to human readable version of syncthru status."""
123  return SYNCTHRU_STATE_HUMAN[self.syncthrusyncthru.device_status()]
124 
125  @property
127  """Show current printer display text."""
128  return {
129  "display_text": self.syncthrusyncthru.device_status_details(),
130  }
131 
132 
134  """Implementation of a Samsung Printer toner sensor platform."""
135 
136  _attr_native_unit_of_measurement = PERCENTAGE
137 
138  def __init__(
139  self, coordinator: DataUpdateCoordinator[SyncThru], name: str, color: str
140  ) -> None:
141  """Initialize the sensor."""
142  super().__init__(coordinator, name)
143  self._attr_name_attr_name_attr_name = f"{name} Toner {color}"
144  self._color_color = color
145  self._id_suffix_id_suffix_id_suffix = f"_toner_{color}"
146 
147  @property
149  """Show all data returned for this toner."""
150  return self.syncthrusyncthru.toner_status().get(self._color_color, {})
151 
152  @property
153  def native_value(self):
154  """Show amount of remaining toner."""
155  return self.syncthrusyncthru.toner_status().get(self._color_color, {}).get("remaining")
156 
157 
159  """Implementation of a Samsung Printer drum sensor platform."""
160 
161  _attr_native_unit_of_measurement = PERCENTAGE
162 
163  def __init__(
164  self, coordinator: DataUpdateCoordinator[SyncThru], name: str, color: str
165  ) -> None:
166  """Initialize the sensor."""
167  super().__init__(coordinator, name)
168  self._attr_name_attr_name_attr_name = f"{name} Drum {color}"
169  self._color_color = color
170  self._id_suffix_id_suffix_id_suffix = f"_drum_{color}"
171 
172  @property
174  """Show all data returned for this drum."""
175  return self.syncthrusyncthru.drum_status().get(self._color_color, {})
176 
177  @property
178  def native_value(self):
179  """Show amount of remaining drum."""
180  return self.syncthrusyncthru.drum_status().get(self._color_color, {}).get("remaining")
181 
182 
184  """Implementation of a Samsung Printer input tray sensor platform."""
185 
186  def __init__(
187  self, coordinator: DataUpdateCoordinator[SyncThru], name: str, number: str
188  ) -> None:
189  """Initialize the sensor."""
190  super().__init__(coordinator, name)
191  self._attr_name_attr_name_attr_name = f"{name} Tray {number}"
192  self._number_number = number
193  self._id_suffix_id_suffix_id_suffix = f"_tray_{number}"
194 
195  @property
197  """Show all data returned for this input tray."""
198  return self.syncthrusyncthru.input_tray_status().get(self._number_number, {})
199 
200  @property
201  def native_value(self):
202  """Display ready unless there is some error, then display error."""
203  tray_state = (
204  self.syncthrusyncthru.input_tray_status().get(self._number_number, {}).get("newError")
205  )
206  if tray_state == "":
207  tray_state = "Ready"
208  return tray_state
209 
210 
212  """Implementation of a Samsung Printer output tray sensor platform."""
213 
214  def __init__(
215  self, coordinator: DataUpdateCoordinator[SyncThru], name: str, number: int
216  ) -> None:
217  """Initialize the sensor."""
218  super().__init__(coordinator, name)
219  self._attr_name_attr_name_attr_name = f"{name} Output Tray {number}"
220  self._number_number = number
221  self._id_suffix_id_suffix_id_suffix = f"_output_tray_{number}"
222 
223  @property
225  """Show all data returned for this output tray."""
226  return self.syncthrusyncthru.output_tray_status().get(self._number_number, {})
227 
228  @property
229  def native_value(self):
230  """Display ready unless there is some error, then display error."""
231  tray_state = (
232  self.syncthrusyncthru.output_tray_status().get(self._number_number, {}).get("status")
233  )
234  if tray_state == "":
235  tray_state = "Ready"
236  return tray_state
237 
238 
240  """Implementation of a Samsung Printer active alerts sensor platform."""
241 
242  def __init__(self, coordinator: DataUpdateCoordinator[SyncThru], name: str) -> None:
243  """Initialize the sensor."""
244  super().__init__(coordinator, name)
245  self._attr_name_attr_name_attr_name = f"{name} Active Alerts"
246  self._id_suffix_id_suffix_id_suffix = "_active_alerts"
247 
248  @property
249  def native_value(self):
250  """Show number of active alerts."""
251  return self.syncthrusyncthru.raw().get("GXI_ACTIVE_ALERT_TOTAL")
None __init__(self, DataUpdateCoordinator[SyncThru] coordinator, str name)
Definition: sensor.py:242
None __init__(self, DataUpdateCoordinator[SyncThru] coordinator, str name, str color)
Definition: sensor.py:165
None __init__(self, DataUpdateCoordinator[SyncThru] coordinator, str name, str number)
Definition: sensor.py:188
None __init__(self, DataUpdateCoordinator[SyncThru] coordinator, str name)
Definition: sensor.py:115
None __init__(self, DataUpdateCoordinator[SyncThru] coordinator, str name, int number)
Definition: sensor.py:216
None __init__(self, DataUpdateCoordinator[SyncThru] coordinator, str name)
Definition: sensor.py:83
None __init__(self, DataUpdateCoordinator[SyncThru] coordinator, str name, str color)
Definition: sensor.py:140
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:47
set[tuple[str, str]]|None device_identifiers(SyncThru printer)
Definition: __init__.py:89