mixin.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. """
  2. Mixins to make writing new platforms easier
  3. """
  4. import logging
  5. from homeassistant.const import (
  6. AREA_SQUARE_METERS,
  7. CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
  8. UnitOfTemperature,
  9. )
  10. from homeassistant.helpers.entity import EntityCategory
  11. from homeassistant.helpers.typing import UNDEFINED
  12. _LOGGER = logging.getLogger(__name__)
  13. class TuyaLocalEntity:
  14. """Common functions for all entity types."""
  15. def _init_begin(self, device, config):
  16. self._device = device
  17. self._config = config
  18. self._attr_dps = []
  19. self._attr_translation_key = config.translation_key
  20. return {c.name: c for c in config.dps()}
  21. def _init_end(self, dps):
  22. for d in dps.values():
  23. if not d.hidden:
  24. self._attr_dps.append(d)
  25. @property
  26. def should_poll(self):
  27. return False
  28. @property
  29. def available(self):
  30. return self._device.has_returned_state
  31. @property
  32. def has_entity_name(self):
  33. return True
  34. @property
  35. def name(self):
  36. """Return the name for the UI."""
  37. # Super has the logic to get default names from device class.
  38. super_name = getattr(super(), "name")
  39. # If we don't have a name, and super also doesn't, we explicitly want to use
  40. # the device name - avoid the HA warning about implicitly using it.
  41. if super_name is UNDEFINED:
  42. super_name = None
  43. return self._config.name or super_name
  44. @property
  45. def unique_id(self):
  46. """Return the unique id for this entity."""
  47. return self._config.unique_id(self._device.unique_id)
  48. @property
  49. def device_info(self):
  50. """Return the device's information."""
  51. return self._device.device_info
  52. @property
  53. def entity_category(self):
  54. """Return the entitiy's category."""
  55. return (
  56. None
  57. if self._config.entity_category is None
  58. else EntityCategory(self._config.entity_category)
  59. )
  60. @property
  61. def icon(self):
  62. """Return the icon to use in the frontend for this device."""
  63. icon = self._config.icon(self._device)
  64. if icon:
  65. return icon
  66. else:
  67. return super().icon
  68. @property
  69. def extra_state_attributes(self):
  70. """Get additional attributes that the platform itself does not support."""
  71. attr = {}
  72. for a in self._attr_dps:
  73. value = a.get_value(self._device)
  74. if value is not None or not a.optional:
  75. attr[a.name] = value
  76. return attr
  77. @property
  78. def entity_registry_enabled_default(self):
  79. """Disable deprecated entities on new installations"""
  80. return not self._config.deprecated
  81. async def async_update(self):
  82. await self._device.async_refresh()
  83. async def async_added_to_hass(self):
  84. self._device.register_entity(self)
  85. async def async_will_remove_from_hass(self):
  86. await self._device.async_unregister_entity(self)
  87. UNIT_ASCII_MAP = {
  88. "C": UnitOfTemperature.CELSIUS,
  89. "F": UnitOfTemperature.FAHRENHEIT,
  90. "ugm3": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
  91. "m2": AREA_SQUARE_METERS,
  92. }
  93. def unit_from_ascii(unit):
  94. if unit in UNIT_ASCII_MAP:
  95. return UNIT_ASCII_MAP[unit]
  96. return unit