select.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. """Select platform for Solar of Things integration."""
  2. from __future__ import annotations
  3. import logging
  4. from typing import Any
  5. from homeassistant.components.select import SelectEntity
  6. from homeassistant.config_entries import ConfigEntry
  7. from homeassistant.core import HomeAssistant
  8. from homeassistant.helpers.entity_platform import AddEntitiesCallback
  9. from homeassistant.helpers.update_coordinator import CoordinatorEntity
  10. from .const import DOMAIN
  11. _LOGGER = logging.getLogger(__name__)
  12. # Operating modes available in the system
  13. OPERATING_MODES = [
  14. "Self-Use",
  15. "Time-of-Use",
  16. "Backup",
  17. "Grid-Tie",
  18. "Off-Grid",
  19. ]
  20. # Battery priority modes
  21. BATTERY_PRIORITY_MODES = [
  22. "Solar First",
  23. "Battery First",
  24. "Grid First",
  25. ]
  26. async def async_setup_entry(
  27. hass: HomeAssistant,
  28. entry: ConfigEntry,
  29. async_add_entities: AddEntitiesCallback,
  30. ) -> None:
  31. """Set up Solar of Things select entities based on a config entry."""
  32. coordinator = hass.data[DOMAIN][entry.entry_id]["coordinator"]
  33. api = hass.data[DOMAIN][entry.entry_id]["api"]
  34. entities = [
  35. SolarOfThingsOperatingModeSelect(
  36. coordinator=coordinator,
  37. entry=entry,
  38. api=api,
  39. ),
  40. SolarOfThingsBatteryPrioritySelect(
  41. coordinator=coordinator,
  42. entry=entry,
  43. api=api,
  44. ),
  45. ]
  46. async_add_entities(entities)
  47. class SolarOfThingsOperatingModeSelect(CoordinatorEntity, SelectEntity):
  48. """Select entity for system operating mode."""
  49. def __init__(
  50. self,
  51. coordinator,
  52. entry: ConfigEntry,
  53. api,
  54. ) -> None:
  55. """Initialize the select entity."""
  56. super().__init__(coordinator)
  57. self._entry = entry
  58. self._api = api
  59. self._attr_name = f"{entry.data.get('station_id', entry.data.get('device_id'))} Operating Mode"
  60. self._attr_unique_id = f"{entry.entry_id}_operating_mode"
  61. self._attr_options = OPERATING_MODES
  62. self._attr_icon = "mdi:cog"
  63. @property
  64. def device_info(self):
  65. """Return device information."""
  66. return {
  67. "identifiers": {(DOMAIN, self._entry.entry_id)},
  68. "name": f"Solar Station {self._entry.data.get('station_id', self._entry.data.get('device_id'))}",
  69. "manufacturer": "Siseli",
  70. "model": "Solar Inverter",
  71. }
  72. @property
  73. def current_option(self) -> str | None:
  74. """Return the current selected option."""
  75. if self.coordinator.data and "settings" in self.coordinator.data:
  76. return self.coordinator.data["settings"].get("operatingMode")
  77. return None
  78. async def async_select_option(self, option: str) -> None:
  79. """Change the selected option."""
  80. try:
  81. await self.hass.async_add_executor_job(
  82. self._api.set_operating_mode,
  83. option
  84. )
  85. # Request immediate coordinator update
  86. await self.coordinator.async_request_refresh()
  87. except Exception as err:
  88. _LOGGER.error("Error setting operating mode: %s", err)
  89. raise
  90. class SolarOfThingsBatteryPrioritySelect(CoordinatorEntity, SelectEntity):
  91. """Select entity for battery priority mode."""
  92. def __init__(
  93. self,
  94. coordinator,
  95. entry: ConfigEntry,
  96. api,
  97. ) -> None:
  98. """Initialize the select entity."""
  99. super().__init__(coordinator)
  100. self._entry = entry
  101. self._api = api
  102. self._attr_name = f"{entry.data.get('station_id', entry.data.get('device_id'))} Battery Priority"
  103. self._attr_unique_id = f"{entry.entry_id}_battery_priority"
  104. self._attr_options = BATTERY_PRIORITY_MODES
  105. self._attr_icon = "mdi:battery-sync"
  106. @property
  107. def device_info(self):
  108. """Return device information."""
  109. return {
  110. "identifiers": {(DOMAIN, self._entry.entry_id)},
  111. "name": f"Solar Station {self._entry.data.get('station_id', self._entry.data.get('device_id'))}",
  112. "manufacturer": "Siseli",
  113. "model": "Solar Inverter",
  114. }
  115. @property
  116. def current_option(self) -> str | None:
  117. """Return the current selected option."""
  118. if self.coordinator.data and "settings" in self.coordinator.data:
  119. return self.coordinator.data["settings"].get("batteryPriority")
  120. return None
  121. async def async_select_option(self, option: str) -> None:
  122. """Change the selected option."""
  123. try:
  124. await self.hass.async_add_executor_job(
  125. self._api.set_battery_priority,
  126. option
  127. )
  128. # Request immediate coordinator update
  129. await self.coordinator.async_request_refresh()
  130. except Exception as err:
  131. _LOGGER.error("Error setting battery priority: %s", err)
  132. raise