Skip to content

Commit

Permalink
Add option to remove additional entities
Browse files Browse the repository at this point in the history
  • Loading branch information
pnbruckner committed Dec 9, 2023
1 parent ff14d49 commit a30b1be
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 16 deletions.
14 changes: 14 additions & 0 deletions custom_components/sun2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import (
CONF_BINARY_SENSORS,
CONF_LATITUDE,
CONF_SENSORS,
CONF_UNIQUE_ID,
Expand All @@ -29,6 +30,7 @@

PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
_OLD_UNIQUE_ID = re.compile(r"[0-9a-f]{32}-([0-9a-f]{32})")
_UUID_UNIQUE_ID = re.compile(r"[0-9a-f]{32}")


async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
Expand Down Expand Up @@ -116,6 +118,18 @@ async def handle_core_config_update(event: Event) -> None:

async def entry_updated(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Handle config entry update."""
# Remove entity registry entries for additional sensors that were deleted.
unqiue_ids = [
sensor[CONF_UNIQUE_ID]
for sensor_type in (CONF_BINARY_SENSORS, CONF_SENSORS)
for sensor in entry.options.get(sensor_type, [])
]
ent_reg = er.async_get(hass)
for entity in er.async_entries_for_config_entry(ent_reg, entry.entry_id):
unique_id = entity.unique_id
# Only sensors that were added via the UI have UUID type unique IDs.
if _UUID_UNIQUE_ID.fullmatch(unique_id) and unique_id not in unqiue_ids:
ent_reg.async_remove(entity.entity_id)
await hass.config_entries.async_reload(entry.entry_id)


Expand Down
76 changes: 74 additions & 2 deletions custom_components/sun2/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import voluptuous as vol

from homeassistant.components.binary_sensor import DOMAIN as BS_DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.config_entries import (
SOURCE_IMPORT,
ConfigEntry,
Expand All @@ -27,6 +29,7 @@
)
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowHandler, FlowResult
from homeassistant.helpers import entity_registry as er
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.selector import (
BooleanSelector,
Expand Down Expand Up @@ -60,6 +63,7 @@ class Sun2Flow(FlowHandler):
"""Sun2 flow mixin."""

_existing_entries: list[ConfigEntry] | None = None
_existing_entities: dict[str, str] | None = None

@property
def _entries(self) -> list[ConfigEntry]:
Expand All @@ -68,6 +72,27 @@ def _entries(self) -> list[ConfigEntry]:
self._existing_entries = self.hass.config_entries.async_entries(DOMAIN)
return self._existing_entries

@property
def _entities(self) -> dict[str, str]:
"""Get existing configured entities."""
if self._existing_entities is not None:
return self._existing_entities

ent_reg = er.async_get(self.hass)
existing_entities: dict[str, str] = {}
for key, domain in {
CONF_BINARY_SENSORS: BS_DOMAIN,
CONF_SENSORS: SENSOR_DOMAIN,
}.items():
for sensor in self.options.get(key, []):
unique_id = cast(str, sensor[CONF_UNIQUE_ID])
entity_id = cast(
str, ent_reg.async_get_entity_id(domain, DOMAIN, unique_id)
)
existing_entities[entity_id] = unique_id
self._existing_entities = existing_entities
return existing_entities

@property
@abstractmethod
def options(self) -> dict[str, Any]:
Expand Down Expand Up @@ -126,13 +151,25 @@ async def async_step_entities_menu(
) -> FlowResult:
"""Handle entity options."""
await init_translations(self.hass)
menu_options = ["add_entities_menu"]
if self.options.get(CONF_BINARY_SENSORS) or self.options.get(CONF_SENSORS):
menu_options.append("remove_entities")
menu_options.append("done")
return self.async_show_menu(step_id="entities_menu", menu_options=menu_options)

async def async_step_add_entities_menu(
self, _: dict[str, Any] | None = None
) -> FlowResult:
"""Add entities."""
menu_options = [
"elevation_binary_sensor",
"elevation_at_time_sensor_menu",
"time_at_elevation_sensor",
"done",
]
return self.async_show_menu(step_id="entities_menu", menu_options=menu_options)
return self.async_show_menu(
step_id="add_entities_menu", menu_options=menu_options
)

async def async_step_elevation_binary_sensor(
self, user_input: dict[str, Any] | None = None
Expand Down Expand Up @@ -269,7 +306,42 @@ async def async_finish_sensor(
"""Finish elevation binary sensor."""
config[CONF_UNIQUE_ID] = random_uuid_hex()
self.options.setdefault(sensor_type, []).append(config)
return await self.async_step_entities_menu()
return await self.async_step_add_entities_menu()

async def async_step_remove_entities(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Remove entities added previously."""

def delete_entity(unique_id: str) -> None:
"""Remove entity with given unique ID."""
for sensor_type in (CONF_BINARY_SENSORS, CONF_SENSORS):
for idx, sensor in enumerate(self.options.get(sensor_type, [])):
if sensor[CONF_UNIQUE_ID] == unique_id:
del self.options[sensor_type][idx]
if not self.options[sensor_type]:
del self.options[sensor_type]
return
assert False

if user_input is not None:
for entity_id in user_input["choices"]:
delete_entity(self._entities[entity_id])
return await self.async_step_done()

entity_ids = list(self._entities)
data_schema = vol.Schema(
{
vol.Required("choices"): EntitySelector(
EntitySelectorConfig(include_entities=entity_ids, multiple=True)
)
}
)
return self.async_show_form(
step_id="remove_entities",
data_schema=data_schema,
last_step=False,
)

@abstractmethod
async def async_step_done(self, _: dict[str, Any] | None = None) -> FlowResult:
Expand Down
37 changes: 30 additions & 7 deletions custom_components/sun2/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
"title": "Sun2",
"config": {
"step": {
"add_entities_menu": {
"title": "Add Entities",
"description": "Choose type of entity to add",
"menu_options": {
"done": "Done",
"elevation_at_time_sensor_menu": "Elevation at time sensor",
"elevation_binary_sensor": "Elevation binary sensor",
"time_at_elevation_sensor": "Time at elevation sensor"
}
},
"elevation_at_time_sensor_menu": {
"title": "Elevation at Time Type",
"menu_options": {
Expand Down Expand Up @@ -39,10 +49,8 @@
"entities_menu": {
"title": "Additional Entities",
"menu_options": {
"done": "Done",
"elevation_at_time_sensor_menu": "Add elevation at time sensor",
"elevation_binary_sensor": "Add elevation binary sensor",
"time_at_elevation_sensor": "Add time at elevation sensor"
"add_entities_menu": "Add entities",
"done": "Done"
}
},
"location": {
Expand Down Expand Up @@ -83,6 +91,16 @@
},
"options": {
"step": {
"add_entities_menu": {
"title": "Add Entities",
"description": "Choose type of entity to add",
"menu_options": {
"done": "Done",
"elevation_at_time_sensor_menu": "Elevation at time sensor",
"elevation_binary_sensor": "Elevation binary sensor",
"time_at_elevation_sensor": "Time at elevation sensor"
}
},
"elevation_at_time_sensor_menu": {
"title": "Elevation at Time Type",
"menu_options": {
Expand Down Expand Up @@ -120,10 +138,9 @@
"entities_menu": {
"title": "Additional Entities",
"menu_options": {
"add_entities_menu": "Add entities",
"done": "Done",
"elevation_at_time_sensor_menu": "Add elevation at time sensor",
"elevation_binary_sensor": "Add elevation binary sensor",
"time_at_elevation_sensor": "Add time at elevation sensor"
"remove_entities": "Remove entities"
}
},
"location": {
Expand All @@ -137,6 +154,12 @@
"time_zone": "See the \"TZ identifier\" column at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List."
}
},
"remove_entities": {
"title": "Remove Entities",
"data": {
"choices": "Select entities to remove"
}
},
"time_at_elevation_sensor": {
"title": "Time at Elevation Sensor Options",
"data": {
Expand Down
37 changes: 30 additions & 7 deletions custom_components/sun2/translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
"title": "Zon2",
"config": {
"step": {
"add_entities_menu": {
"title": "Entiteiten toevoegen",
"description": "Kies het type entiteit dat u wilt toevoegen",
"menu_options": {
"done": "Klaar",
"elevation_at_time_sensor_menu": "Hoogte toevoegen bij tijdsensor",
"elevation_binary_sensor": "Binaire sensor voor elevatie toevoegen",
"time_at_elevation_sensor": "Tijd toevoegen bij hoogtesensor"
}
},
"elevation_at_time_sensor_menu": {
"title": "Hoogte op tijdtype",
"menu_options": {
Expand Down Expand Up @@ -39,10 +49,8 @@
"entities_menu": {
"title": "Aanvullende entiteiten",
"menu_options": {
"done": "Klaar",
"elevation_at_time_sensor_menu": "Hoogte toevoegen bij tijdsensor",
"elevation_binary_sensor": "Binaire sensor voor elevatie toevoegen",
"time_at_elevation_sensor": "Tijd toevoegen bij hoogtesensor"
"add_entities_menu": "Entiteiten toevoegen",
"done": "Klaar"
}
},
"location": {
Expand Down Expand Up @@ -83,6 +91,16 @@
},
"options": {
"step": {
"add_entities_menu": {
"title": "Entiteiten toevoegen",
"description": "Kies het type entiteit dat u wilt toevoegen",
"menu_options": {
"done": "Klaar",
"elevation_at_time_sensor_menu": "Hoogte toevoegen bij tijdsensor",
"elevation_binary_sensor": "Binaire sensor voor elevatie toevoegen",
"time_at_elevation_sensor": "Tijd toevoegen bij hoogtesensor"
}
},
"elevation_at_time_sensor_menu": {
"title": "Hoogte op tijdtype",
"menu_options": {
Expand Down Expand Up @@ -120,10 +138,9 @@
"entities_menu": {
"title": "Aanvullende entiteiten",
"menu_options": {
"add_entities_menu": "Entiteiten toevoegen",
"done": "Klaar",
"elevation_at_time_sensor_menu": "Hoogte toevoegen bij tijdsensor",
"elevation_binary_sensor": "Binaire sensor voor elevatie toevoegen",
"time_at_elevation_sensor": "Tijd toevoegen bij hoogtesensor"
"remove_entities": "Entiteiten verwijderen"
}
},
"location": {
Expand All @@ -137,6 +154,12 @@
"time_zone": "Zie de kolom \"TZ identifier\" bij https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List."
}
},
"remove_entities": {
"title": "Entiteiten verwijderen",
"data": {
"choices": "Entiteiten selecteren die u wilt verwijderen"
}
},
"time_at_elevation_sensor": {
"title": "Opties voor tijdsensor op hoogte",
"data": {
Expand Down

0 comments on commit a30b1be

Please sign in to comment.