Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions custom_components/roborock_custom_map/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,48 @@

from __future__ import annotations

from homeassistant.config_entries import ConfigEntry
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady

PLATFORMS = [Platform.IMAGE]
from .const import CONF_MAP_ROTATION, DOMAIN

PLATFORMS = [Platform.IMAGE, Platform.SELECT]


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Roborock Custom map from a config entry."""
roborock_entries = hass.config_entries.async_entries("roborock")
coordinators = []

async def unload_this_entry():
await hass.config_entries.async_reload(entry.entry_id)
@callback
def unload_this_entry() -> None:
hass.async_create_task(hass.config_entries.async_reload(entry.entry_id))

for r_entry in roborock_entries:
if r_entry.state == ConfigEntryState.LOADED:
coordinators.extend(r_entry.runtime_data.v1)
# If any unload, then we should reload as well in case there are major changes.
r_entry.async_on_unload(unload_this_entry)
if len(coordinators) == 0:

r_entry.async_on_unload(unload_this_entry)

if not coordinators:
raise ConfigEntryNotReady("No Roborock entries loaded. Cannot start.")

entry.runtime_data = coordinators

hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN].setdefault(entry.entry_id, {})
hass.data[DOMAIN][entry.entry_id].setdefault(CONF_MAP_ROTATION, {})

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

return True


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
unloaded = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unloaded:
hass.data.get(DOMAIN, {}).pop(entry.entry_id, None)
return unloaded
81 changes: 80 additions & 1 deletion custom_components/roborock_custom_map/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,25 @@

from __future__ import annotations

from copy import deepcopy
from typing import Any

import voluptuous as vol

from homeassistant import config_entries
from homeassistant.config_entries import OptionsFlowWithReload
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult

from .const import DOMAIN
from .const import (
CONF_SHOW_BACKGROUND,
CONF_SHOW_FLOOR,
CONF_SHOW_ROOMS,
CONF_SHOW_WALLS,
DEFAULT_DRAWABLES,
DOMAIN,
DRAWABLES,
)


class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
Expand All @@ -22,3 +35,69 @@ async def async_step_user(
self.async_set_unique_id(DOMAIN)
self._abort_if_unique_id_configured()
return self.async_create_entry(title="Roborock Custom Map", data={})

@staticmethod
@callback
def async_get_options_flow(config_entry) -> RoborockCustomMapOptionsFlow:
"""Create the options flow."""
return RoborockCustomMapOptionsFlow(config_entry)


class RoborockCustomMapOptionsFlow(OptionsFlowWithReload):
"""Handle options for Roborock Custom Map."""

def __init__(self, config_entry) -> None:
"""Initialize options flow."""
self.options = deepcopy(dict(config_entry.options))

async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Manage the options."""
if user_input is not None:
self.options[CONF_SHOW_BACKGROUND] = user_input.pop(CONF_SHOW_BACKGROUND)
self.options[CONF_SHOW_WALLS] = user_input.pop(CONF_SHOW_WALLS)
self.options[CONF_SHOW_ROOMS] = user_input.pop(CONF_SHOW_ROOMS)
self.options[CONF_SHOW_FLOOR] = user_input.pop(CONF_SHOW_FLOOR)
self.options.setdefault(DRAWABLES, {}).update(user_input)
return self.async_create_entry(title="", data=self.options)

data_schema: dict = {}
for drawable, default_value in DEFAULT_DRAWABLES.items():
data_schema[
vol.Required(
drawable.value,
default=self.config_entry.options.get(DRAWABLES, {}).get(
drawable.value, default_value
),
)
] = bool
data_schema[
vol.Required(
CONF_SHOW_BACKGROUND,
default=self.config_entry.options.get(CONF_SHOW_BACKGROUND, True),
)
] = bool
data_schema[
vol.Required(
CONF_SHOW_WALLS,
default=self.config_entry.options.get(CONF_SHOW_WALLS, True),
)
] = bool
data_schema[
vol.Required(
CONF_SHOW_ROOMS,
default=self.config_entry.options.get(CONF_SHOW_ROOMS, True),
)
] = bool
data_schema[
vol.Required(
CONF_SHOW_FLOOR,
default=self.config_entry.options.get(CONF_SHOW_FLOOR, True),
)
] = bool

return self.async_show_form(
step_id="init",
data_schema=vol.Schema(data_schema),
)
33 changes: 33 additions & 0 deletions custom_components/roborock_custom_map/const.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
"""Constants for Roborock Custom Map integration."""

from vacuum_map_parser_base.config.drawable import Drawable

DOMAIN = "roborock_custom_map"

CONF_MAP_ROTATION = "map_rotation"
DEFAULT_MAP_ROTATION = 0
MAP_ROTATION_OPTIONS = (0, 90, 180, 270)

SIGNAL_ROTATION_CHANGED = "roborock_custom_map_rotation_changed"

CONF_SHOW_BACKGROUND = "show_background"
CONF_SHOW_WALLS = "show_walls"
CONF_SHOW_ROOMS = "show_rooms"
CONF_SHOW_FLOOR = "show_floor"
DRAWABLES = "drawables"

DEFAULT_DRAWABLES = {
Drawable.CHARGER: True,
Drawable.CLEANED_AREA: False,
Drawable.GOTO_PATH: False,
Drawable.IGNORED_OBSTACLES: False,
Drawable.IGNORED_OBSTACLES_WITH_PHOTO: False,
Drawable.MOP_PATH: False,
Drawable.NO_CARPET_AREAS: False,
Drawable.NO_GO_AREAS: False,
Drawable.NO_MOPPING_AREAS: False,
Drawable.OBSTACLES: False,
Drawable.OBSTACLES_WITH_PHOTO: False,
Drawable.PATH: True,
Drawable.PREDICTED_PATH: False,
Drawable.VACUUM_POSITION: True,
Drawable.VIRTUAL_WALLS: False,
Drawable.ZONES: False,
}
Loading