Checklist
Describe the issue
The Timeline Language setting (and likely Retention Time) configured under LLM Vision Settings → Reconfigure → Timeline is silently ignored at runtime, no matter what value is selected in the UI. Event classification (category/label columns in events.db) always falls back to English keyword matching, even when the dropdown clearly shows a different language (e.g. Polish) and that value persists across reopening the settings form.
Root cause
The Settings config flow (config_flow.py, async_step_settings) saves the form back to the config entry using:
return self.async_update_reload_and_abort(
self._get_reconfigure_entry(),
data_updates=user_input,
)
This writes the selected values (including timeline_language) into config_entry.data.
However, timeline.py reads the language setting from a different attribute:
# timeline.py, line 34
language = config_entry.options.get(CONF_TIMELINE_LANGUAGE) or "English"
config_entry.options is never populated anywhere in the codebase for this entry — every other setting (system_prompt, title_prompt, retention_time in __init__.py, memory paths, provider config, etc.) is consistently read via config_entry.data.get(...). Only two call sites use .options instead:
timeline.py:34 — CONF_TIMELINE_LANGUAGE
timeline.py:521 — CONF_RETENTION_TIME (inconsistent with __init__.py:118, which correctly reads entry.data.get(CONF_RETENTION_TIME))
Because .options is always an empty dict for this entry, .get(CONF_TIMELINE_LANGUAGE) always returns None, so the code always falls back to "English" regardless of what the user configured. This means _get_category_and_label() always loads timeline_strings/en.json, so any non-English word in the event title/description never matches, and category/label stay empty for every user not using English — silently breaking automatic icon assignment in the Timeline Card for every non-English installation.
Expected behavior
category/label should be populated according to the language selected in Settings.
Actual behavior
category/label are always empty (equivalent to always using English matching), regardless of the configured Timeline Language.
Suggested fix
Change timeline.py:34 and timeline.py:521 to read from config_entry.data instead of config_entry.options, matching the rest of the codebase:
language = config_entry.data.get(CONF_TIMELINE_LANGUAGE) or "English"
Reproduction steps
- Open LLM Vision Settings → Reconfigure → Timeline and set Language to anything other than English (e.g. Polish).
- Save. Reopen the form — the selected language is shown correctly (confirms it is saved somewhere).
- Trigger a camera event whose title contains a word that exists in the corresponding
timeline_strings/<lang>.json (e.g. Polish "osoba").
- Inspect the new row in
events.db (or the calendar entity's event data) — category and label are empty strings, even though the word should have matched.
Debug logs
- Verified by direct inspection of `events.db`: an event with description containing a Polish word had empty `category`/`label` before the fix, and correctly populated `category='person', label='person'` after changing `.options` to `.data` at line 34 and restarting.
- Confirmed via source review that every other config value in `__init__.py` and `memory.py` is read via `entry.data.get(...)`, making these two `.options` reads clear outliers rather than intentional design.
Checklist
Describe the issue
The Timeline Language setting (and likely Retention Time) configured under LLM Vision Settings → Reconfigure → Timeline is silently ignored at runtime, no matter what value is selected in the UI. Event classification (
category/labelcolumns inevents.db) always falls back to English keyword matching, even when the dropdown clearly shows a different language (e.g. Polish) and that value persists across reopening the settings form.Root cause
The Settings config flow (
config_flow.py,async_step_settings) saves the form back to the config entry using:This writes the selected values (including
timeline_language) intoconfig_entry.data.However,
timeline.pyreads the language setting from a different attribute:config_entry.optionsis never populated anywhere in the codebase for this entry — every other setting (system_prompt,title_prompt,retention_timein__init__.py, memory paths, provider config, etc.) is consistently read viaconfig_entry.data.get(...). Only two call sites use.optionsinstead:timeline.py:34—CONF_TIMELINE_LANGUAGEtimeline.py:521—CONF_RETENTION_TIME(inconsistent with__init__.py:118, which correctly readsentry.data.get(CONF_RETENTION_TIME))Because
.optionsis always an empty dict for this entry,.get(CONF_TIMELINE_LANGUAGE)always returnsNone, so the code always falls back to"English"regardless of what the user configured. This means_get_category_and_label()always loadstimeline_strings/en.json, so any non-English word in the event title/description never matches, andcategory/labelstay empty for every user not using English — silently breaking automatic icon assignment in the Timeline Card for every non-English installation.Expected behavior
category/labelshould be populated according to the language selected in Settings.Actual behavior
category/labelare always empty (equivalent to always using English matching), regardless of the configured Timeline Language.Suggested fix
Change
timeline.py:34andtimeline.py:521to read fromconfig_entry.datainstead ofconfig_entry.options, matching the rest of the codebase:Reproduction steps
timeline_strings/<lang>.json(e.g. Polish "osoba").events.db(or the calendar entity's event data) —categoryandlabelare empty strings, even though the word should have matched.Debug logs