Updated ics_calendar to restore compatibility with HA

This commit is contained in:
2025-05-08 10:02:22 +02:00
parent fef90d5a78
commit ca599eab7a
21 changed files with 1329 additions and 234 deletions

View File

@@ -4,6 +4,7 @@ import logging
import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import (
CONF_EXCLUDE,
CONF_INCLUDE,
@@ -14,24 +15,35 @@ from homeassistant.const import (
CONF_USERNAME,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import discovery
from homeassistant.helpers.issue_registry import (
IssueSeverity,
async_create_issue,
)
from homeassistant.helpers.typing import ConfigType
from .const import DOMAIN, UPGRADE_URL
from .const import (
CONF_ACCEPT_HEADER,
CONF_ADV_CONNECT_OPTS,
CONF_CALENDARS,
CONF_CONNECTION_TIMEOUT,
CONF_DAYS,
CONF_DOWNLOAD_INTERVAL,
CONF_INCLUDE_ALL_DAY,
CONF_OFFSET_HOURS,
CONF_PARSER,
CONF_REQUIRES_AUTH,
CONF_SET_TIMEOUT,
CONF_SUMMARY_DEFAULT,
CONF_SUMMARY_DEFAULT_DEFAULT,
CONF_USER_AGENT,
DOMAIN,
)
_LOGGER = logging.getLogger(__name__)
PLATFORMS: list[Platform] = [Platform.CALENDAR]
CONF_DEVICE_ID = "device_id"
CONF_CALENDARS = "calendars"
CONF_DAYS = "days"
CONF_INCLUDE_ALL_DAY = "include_all_day"
CONF_PARSER = "parser"
CONF_DOWNLOAD_INTERVAL = "download_interval"
CONF_USER_AGENT = "user_agent"
CONF_OFFSET_HOURS = "offset_hours"
CONF_ACCEPT_HEADER = "accept_header"
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
@@ -81,6 +93,13 @@ CONFIG_SCHEMA = vol.Schema(
vol.Optional(
CONF_ACCEPT_HEADER, default=""
): cv.string,
vol.Optional(
CONF_CONNECTION_TIMEOUT, default=300
): cv.positive_float,
vol.Optional(
CONF_SUMMARY_DEFAULT,
default=CONF_SUMMARY_DEFAULT_DEFAULT,
): cv.string,
}
)
]
@@ -92,22 +111,150 @@ CONFIG_SCHEMA = vol.Schema(
extra=vol.ALLOW_EXTRA,
)
STORAGE_KEY = DOMAIN
STORAGE_VERSION_MAJOR = 1
STORAGE_VERSION_MINOR = 0
def setup(hass: HomeAssistant, config: ConfigType) -> bool:
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up calendars."""
_LOGGER.debug("Setting up ics_calendar component")
hass.data.setdefault(DOMAIN, {})
if DOMAIN in config and config[DOMAIN]:
hass.helpers.discovery.load_platform(
PLATFORMS[0], DOMAIN, config[DOMAIN], config
_LOGGER.debug("discovery.load_platform called")
discovery.load_platform(
hass=hass,
component=PLATFORMS[0],
platform=DOMAIN,
discovered=config[DOMAIN],
hass_config=config,
)
else:
_LOGGER.error(
"No configuration found! If you upgraded from ics_calendar v3.2.0 "
"or older, you need to update your configuration! See "
"%s for more information.",
UPGRADE_URL,
async_create_issue(
hass,
DOMAIN,
"deprecated_yaml_configuration",
is_fixable=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="YAML_Warning",
)
_LOGGER.warning(
"YAML configuration of ics_calendar is deprecated and will be "
"removed in ics_calendar v5.0.0. Your configuration items have "
"been imported. Please remove them from your configuration.yaml "
"file."
)
config_entry = _async_find_matching_config_entry(hass)
if not config_entry:
if config[DOMAIN].get("calendars"):
for calendar in config[DOMAIN].get("calendars"):
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=dict(calendar),
)
)
return True
# update entry with any changes
if config[DOMAIN].get("calendars"):
for calendar in config[DOMAIN].get("calendars"):
hass.config_entries.async_update_entry(
config_entry, data=dict(calendar)
)
return True
@callback
def _async_find_matching_config_entry(hass):
for entry in hass.config_entries.async_entries(DOMAIN):
if entry.source == SOURCE_IMPORT:
return entry
return None
async def async_migrate_entry(hass, entry: ConfigEntry):
"""Migrate old config entry."""
# Don't downgrade entries
if entry.version > STORAGE_VERSION_MAJOR:
return False
if entry.version == STORAGE_VERSION_MAJOR:
new_data = {**entry.data}
hass.config_entries.async_update_entry(
entry,
data=new_data,
minor_version=STORAGE_VERSION_MINOR,
version=STORAGE_VERSION_MAJOR,
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Implement async_setup_entry."""
full_data: dict = add_missing_defaults(entry)
hass.config_entries.async_update_entry(entry=entry, data=full_data)
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = full_data
await hass.config_entries.async_forward_entry_setups(entry, ["calendar"])
return True
def add_missing_defaults(
entry: ConfigEntry,
) -> dict:
"""Initialize missing data."""
data = {
CONF_NAME: "",
CONF_URL: "",
CONF_ADV_CONNECT_OPTS: False,
CONF_SET_TIMEOUT: False,
CONF_REQUIRES_AUTH: False,
CONF_INCLUDE_ALL_DAY: False,
CONF_REQUIRES_AUTH: False,
CONF_USERNAME: "",
CONF_PASSWORD: "",
CONF_PARSER: "rie",
CONF_PREFIX: "",
CONF_DAYS: 1,
CONF_DOWNLOAD_INTERVAL: 15,
CONF_USER_AGENT: "",
CONF_EXCLUDE: "",
CONF_INCLUDE: "",
CONF_OFFSET_HOURS: 0,
CONF_ACCEPT_HEADER: "",
CONF_CONNECTION_TIMEOUT: 300.0,
CONF_SUMMARY_DEFAULT: CONF_SUMMARY_DEFAULT_DEFAULT,
}
data.update(entry.data)
if CONF_USERNAME in entry.data or CONF_PASSWORD in entry.data:
data[CONF_REQUIRES_AUTH] = True
if (
CONF_USER_AGENT in entry.data
or CONF_ACCEPT_HEADER in entry.data
or CONF_CONNECTION_TIMEOUT in entry.data
):
data[CONF_ADV_CONNECT_OPTS] = True
if CONF_CONNECTION_TIMEOUT in entry.data:
data[CONF_SET_TIMEOUT] = True
return data
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload entry."""
unload_ok = await hass.config_entries.async_unload_platforms(
entry, PLATFORMS
)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok