Fix ImmichFrame config: map env_vars and schema options to Settings.yaml

- Add General display options (Interval, ShowClock, etc.) to addon config schema
- Add per-Account filter options (Albums, People, ShowFavorites, etc.) to Accounts schema
- Rewrite 99-run.sh to generate complete Settings.yaml with General and Accounts sections
- env_vars are automatically classified as General or Account-level settings
- Schema options take precedence over env_vars
- Full backward compatibility: existing env_var configs continue to work
- Update README with comprehensive options documentation
- Bump version to 1.0.32.0-4

Co-authored-by: alexbelgium <44178713+alexbelgium@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-17 09:03:46 +00:00
parent a63c15031b
commit 41fe7d3bb0
4 changed files with 306 additions and 39 deletions

View File

@@ -1,3 +1,10 @@
## 1.0.32.0-4 (17-03-2026)
- Fix: env_vars now properly written to Settings.yaml instead of only environment variables
- Added General config options to addon UI (Interval, ShowClock, PhotoDateFormat, Style, Layout, etc.)
- Added per-Account config options to addon UI (Albums, People, ShowFavorites, ShowMemories, etc.)
- env_vars are automatically classified as General or Account settings in Settings.yaml
- Full backward compatibility: existing env_vars configurations continue to work
## 1.0.32.0-3 (16-03-2026)
- Minor bugs fixed

View File

@@ -39,12 +39,71 @@ Webui can be found at `<your-ip>:8171`.
### Options
#### Connection
| Option | Type | Description |
|--------|------|-------------|
| `ImmichServerUrl` | str | URL of your Immich server (e.g., `http://homeassistant:3001`). Used for single-account setup. |
| `ApiKey` | str | Immich API key for authentication. Used for single-account setup. |
| `Accounts` | list | List of Immich accounts for multi-account support. Each entry requires `ImmichServerUrl` and `ApiKey`, plus optional per-account filters (see below). |
| `TZ` | str | Timezone (e.g., `Europe/London`) |
#### General (Display) Options
These top-level options map to ImmichFrame's `General` settings and control the display behavior:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `ImmichServerUrl` | str | | URL of your Immich server (e.g., `http://homeassistant:3001`). Used for single-account setup. |
| `ApiKey` | str | | Immich API key for authentication. Used for single-account setup. |
| `Accounts` | list | `[]` | List of Immich accounts for multi-account support. Each entry requires `ImmichServerUrl` and `ApiKey`. |
| `TZ` | str | | Timezone (e.g., `Europe/London`) |
| `Interval` | int | 45 | Image display interval in seconds |
| `TransitionDuration` | float | 2 | Transition duration in seconds |
| `ShowClock` | bool | true | Display the current time |
| `ClockFormat` | str | `hh:mm` | Time format for the clock |
| `ClockDateFormat` | str | `eee, MMM d` | Date format for the clock |
| `ShowProgressBar` | bool | true | Display the progress bar |
| `ShowPhotoDate` | bool | true | Display the date of the current image |
| `PhotoDateFormat` | str | `MM/dd/yyyy` | Date format for photo dates |
| `ShowImageDesc` | bool | true | Display image description |
| `ShowPeopleDesc` | bool | true | Display people names |
| `ShowTagsDesc` | bool | true | Display tag names |
| `ShowAlbumName` | bool | true | Display album names |
| `ShowImageLocation` | bool | true | Display image location |
| `ShowWeatherDescription` | bool | true | Display weather description |
| `ImageZoom` | bool | true | Zoom into images for a touch of life |
| `ImagePan` | bool | false | Pan images in a random direction |
| `ImageFill` | bool | false | Fill available space (may crop) |
| `PlayAudio` | bool | false | Play audio for videos with audio tracks |
| `PrimaryColor` | str | `#f5deb3` | Primary UI color (hex) |
| `SecondaryColor` | str | `#000000` | Secondary UI color (hex) |
| `Style` | str | `none` | Background style: `none`, `solid`, `transition`, `blur` |
| `Layout` | str | `splitview` | Layout: `single` or `splitview` |
| `BaseFontSize` | str | `17px` | Base font size (CSS format) |
| `Language` | str | `en` | 2-digit ISO language code |
| `WeatherApiKey` | str | | OpenWeatherMap API key |
| `UnitSystem` | str | `imperial` | `imperial` or `metric` |
| `WeatherLatLong` | str | | Weather location as `lat,lon` |
| `ImageLocationFormat` | str | `City,State,Country` | Location display format |
| `DownloadImages` | bool | false | Download images to server |
| `RenewImagesDuration` | int | 30 | Re-download images after this many days |
| `RefreshAlbumPeopleInterval` | int | 12 | Hours between album/people refresh |
#### Per-Account Options
These options can be set within each `Accounts` entry to control which images are shown:
| Option | Type | Description |
|--------|------|-------------|
| `Albums` | str | Comma-separated album UUIDs |
| `ExcludedAlbums` | str | Comma-separated excluded album UUIDs |
| `People` | str | Comma-separated people UUIDs |
| `Tags` | str | Comma-separated tag paths (e.g., `Vacation,Travel/Europe`) |
| `ShowFavorites` | bool | Show favorite images |
| `ShowMemories` | bool | Show memory images |
| `ShowArchived` | bool | Show archived images |
| `ShowVideos` | bool | Include video assets |
| `ImagesFromDays` | int | Show images from the last X days |
| `ImagesFromDate` | str | Show images after this date |
| `ImagesUntilDate` | str | Show images before this date |
| `Rating` | int | Filter by star rating (-1 to 5) |
### Single Account Example
@@ -52,6 +111,9 @@ Webui can be found at `<your-ip>:8171`.
ImmichServerUrl: "http://homeassistant:3001"
ApiKey: "your-immich-api-key-here"
TZ: "Europe/London"
ShowClock: false
Interval: 30
PhotoDateFormat: "dd/MM/yyyy"
```
### Multi-Account Example
@@ -62,8 +124,13 @@ To display photos from multiple Immich accounts (e.g., you and your partner), us
Accounts:
- ImmichServerUrl: "http://homeassistant:3001"
ApiKey: "api-key-for-user-1"
Albums: "album-uuid-1,album-uuid-2"
ShowFavorites: true
- ImmichServerUrl: "http://homeassistant:3001"
ApiKey: "api-key-for-user-2"
People: "person-uuid-1,person-uuid-2"
ShowClock: false
Interval: 40
TZ: "Europe/London"
```
@@ -84,7 +151,16 @@ For more configuration options, see the [ImmichFrame documentation](https://immi
This addon supports custom scripts and environment variables through the `addon_config` mapping:
- **Custom scripts**: See [Running Custom Scripts in Addons](https://github.com/alexbelgium/hassio-addons/wiki/Running-custom-scripts-in-Addons)
- **env_vars option**: Use the add-on `env_vars` option to pass extra environment variables (uppercase or lowercase names). See https://github.com/alexbelgium/hassio-addons/wiki/Add-Environment-variables-to-your-Addon-2 for details.
- **env_vars option**: Use the add-on `env_vars` option to pass extra ImmichFrame settings not available in the addon UI. Environment variables are automatically classified as General or Account-level settings and written to `Settings.yaml`. See https://github.com/alexbelgium/hassio-addons/wiki/Add-Environment-variables-to-your-Addon-2 for details.
**env_vars example** (for settings not in the UI):
```yaml
env_vars:
- name: AuthenticationSecret
value: "my-secret"
- name: Webhook
value: "http://example.com/notify"
```
## Installation

View File

@@ -19,13 +19,56 @@ schema:
Accounts:
- ImmichServerUrl: str
ApiKey: str
Albums: str?
ExcludedAlbums: str?
People: str?
Tags: str?
ShowFavorites: bool?
ShowMemories: bool?
ShowArchived: bool?
ShowVideos: bool?
ImagesFromDays: int?
ImagesFromDate: str?
ImagesUntilDate: str?
Rating: int?
env_vars:
- name: match(^[A-Za-z0-9_]+$)
value: str?
ApiKey: str?
ImmichServerUrl: str?
TZ: str?
Interval: int?
TransitionDuration: float?
ShowClock: bool?
ClockFormat: str?
ClockDateFormat: str?
ShowProgressBar: bool?
ShowPhotoDate: bool?
PhotoDateFormat: str?
ShowImageDesc: bool?
ShowPeopleDesc: bool?
ShowTagsDesc: bool?
ShowAlbumName: bool?
ShowImageLocation: bool?
ShowWeatherDescription: bool?
ImageZoom: bool?
ImagePan: bool?
ImageFill: bool?
PlayAudio: bool?
PrimaryColor: str?
SecondaryColor: str?
Style: str?
Layout: str?
BaseFontSize: str?
Language: str?
WeatherApiKey: str?
UnitSystem: str?
WeatherLatLong: str?
ImageLocationFormat: str?
DownloadImages: bool?
RenewImagesDuration: int?
RefreshAlbumPeopleInterval: int?
slug: immich_frame
url: https://github.com/alexbelgium/hassio-addons
version: "1.0.32.0-3"
version: "1.0.32.0-4"
webui: http://[HOST]:[PORT:8080]

View File

@@ -22,45 +22,186 @@ if [ ! -e /app/Config ]; then
ln -sf /config/Config /app/Config
fi
# Generate Settings.yaml from addon options for multi-account support
# ---- Settings.yaml generation ----
SETTINGS_FILE="/config/Config/Settings.yaml"
ACCOUNT_COUNT=$(jq '.Accounts // [] | length' /data/options.json 2>/dev/null || echo 0)
if [ "$ACCOUNT_COUNT" -gt 0 ]; then
bashio::log.info "Configuring ${ACCOUNT_COUNT} account(s) from Accounts list"
{
# Known account-level setting names (ImmichFrame v2 config)
ACCOUNT_KEYS=" ImmichServerUrl ApiKey ApiKeyFile Albums ExcludedAlbums People Tags ShowFavorites ShowMemories ShowArchived ShowVideos ImagesFromDays ImagesFromDate ImagesUntilDate Rating "
# Settings that accept comma-separated values and should become YAML lists
LIST_KEYS=" Albums ExcludedAlbums People Tags Webcalendars "
# Helper: check if word is in a space-padded list
in_list() { [[ "$2" == *" $1 "* ]]; }
# Helper: read a value from options.json handling booleans and nulls correctly
config_val() {
jq -r "($1) as \$v | if \$v == null then \"\" else (\$v | tostring) end" /data/options.json 2>/dev/null
}
config_has() {
jq -e "($1) != null" /data/options.json >/dev/null 2>&1
}
# Helper: write a YAML key-value pair with proper formatting
yaml_kv() {
local indent="$1" key="$2" value="$3"
# List-type settings -> YAML array
if in_list "$key" "$LIST_KEYS"; then
echo "${indent}${key}:"
IFS=',' read -ra ITEMS <<< "$value"
for item in "${ITEMS[@]}"; do
item="$(echo "$item" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
[ -n "$item" ] && echo "${indent} - '${item//\'/\'\'}'"
done
return
fi
# Boolean
if [ "$value" = "true" ] || [ "$value" = "false" ]; then
echo "${indent}${key}: ${value}"
return
fi
# Integer
if [[ "$value" =~ ^-?[0-9]+$ ]]; then
echo "${indent}${key}: ${value}"
return
fi
# Float
if [[ "$value" =~ ^-?[0-9]+\.[0-9]+$ ]]; then
echo "${indent}${key}: ${value}"
return
fi
# String (single-quoted with escaping)
echo "${indent}${key}: '${value//\'/\'\'}'"
}
# ---- Classify env_vars into general vs account settings ----
declare -A GENERAL_ENVS
declare -A ACCOUNT_ENVS
ENV_COUNT=$(jq '.env_vars // [] | length' /data/options.json 2>/dev/null || echo 0)
if [ "$ENV_COUNT" -gt 0 ]; then
bashio::log.info "Processing ${ENV_COUNT} env_var(s) for Settings.yaml"
fi
for idx in $(seq 0 $((ENV_COUNT - 1))); do
ENAME=$(jq -r ".env_vars[${idx}].name" /data/options.json)
EVALUE=$(jq -r ".env_vars[${idx}].value // \"\"" /data/options.json)
[ -z "$ENAME" ] && continue
[ -z "$EVALUE" ] && continue
[ "$ENAME" = "TZ" ] && continue # TZ is a system env var, not an ImmichFrame setting
if in_list "$ENAME" "$ACCOUNT_KEYS"; then
ACCOUNT_ENVS["$ENAME"]="$EVALUE"
bashio::log.info " env_var ${ENAME} -> Account setting"
else
GENERAL_ENVS["$ENAME"]="$EVALUE"
bashio::log.info " env_var ${ENAME} -> General setting"
fi
done
# General options from the addon schema
GENERAL_SCHEMA_OPTS="Interval TransitionDuration ShowClock ClockFormat ClockDateFormat
ShowProgressBar ShowPhotoDate PhotoDateFormat ShowImageDesc ShowPeopleDesc
ShowTagsDesc ShowAlbumName ShowImageLocation ShowWeatherDescription
ImageZoom ImagePan ImageFill PlayAudio PrimaryColor SecondaryColor Style
Layout BaseFontSize Language WeatherApiKey UnitSystem WeatherLatLong
ImageLocationFormat DownloadImages RenewImagesDuration RefreshAlbumPeopleInterval"
# Per-account options from the addon schema (besides ImmichServerUrl/ApiKey)
ACCOUNT_SCHEMA_OPTS="Albums ExcludedAlbums People Tags ShowFavorites ShowMemories
ShowArchived ShowVideos ImagesFromDays ImagesFromDate ImagesUntilDate Rating"
# ---- Build Settings.yaml ----
{
# -- General section --
GENERAL_STARTED=false
for opt in $GENERAL_SCHEMA_OPTS; do
if config_has ".$opt"; then
$GENERAL_STARTED || { echo "General:"; GENERAL_STARTED=true; }
yaml_kv " " "$opt" "$(config_val ".$opt")"
fi
done
# Add general env_vars (skip if already set via schema option)
for key in "${!GENERAL_ENVS[@]}"; do
if ! config_has ".$key"; then
$GENERAL_STARTED || { echo "General:"; GENERAL_STARTED=true; }
yaml_kv " " "$key" "${GENERAL_ENVS[$key]}"
fi
done
# -- Accounts section --
ACCOUNT_COUNT=$(jq '.Accounts // [] | length' /data/options.json 2>/dev/null || echo 0)
if [ "$ACCOUNT_COUNT" -gt 0 ]; then
bashio::log.info "Configuring ${ACCOUNT_COUNT} account(s) from Accounts list"
echo "Accounts:"
for i in $(seq 0 $((ACCOUNT_COUNT - 1))); do
SERVER_URL=$(jq -r ".Accounts[${i}].ImmichServerUrl" /data/options.json)
API_KEY=$(jq -r ".Accounts[${i}].ApiKey" /data/options.json)
# Escape single quotes for YAML single-quoted strings
SERVER_URL="${SERVER_URL//\'/\'\'}"
API_KEY="${API_KEY//\'/\'\'}"
echo " - ImmichServerUrl: '${SERVER_URL}'"
echo " ApiKey: '${API_KEY}'"
bashio::log.info " Account $((i + 1)): ${SERVER_URL}"
SRV="$(config_val ".Accounts[${i}].ImmichServerUrl")"
KEY="$(config_val ".Accounts[${i}].ApiKey")"
echo " - ImmichServerUrl: '${SRV//\'/\'\'}'"
echo " ApiKey: '${KEY//\'/\'\'}'"
for opt in $ACCOUNT_SCHEMA_OPTS; do
if config_has ".Accounts[${i}].${opt}"; then
yaml_kv " " "$opt" "$(config_val ".Accounts[${i}].${opt}")"
fi
done
# Apply account-level env_vars (only if not already set in this account's schema)
for key in "${!ACCOUNT_ENVS[@]}"; do
in_list "$key" " ImmichServerUrl ApiKey " && continue
if ! config_has ".Accounts[${i}].${key}"; then
yaml_kv " " "$key" "${ACCOUNT_ENVS[$key]}"
fi
done
bashio::log.info " Account $((i + 1)): ${SRV}"
done
} > "${SETTINGS_FILE}"
chmod 600 "${SETTINGS_FILE}"
bashio::log.info "Settings.yaml generated at ${SETTINGS_FILE}"
elif bashio::config.has_value 'ApiKey' && bashio::config.has_value 'ImmichServerUrl'; then
bashio::log.info "Using single account configuration"
SERVER_URL=$(bashio::config 'ImmichServerUrl')
API_KEY=$(bashio::config 'ApiKey')
# Escape single quotes for YAML single-quoted strings
SERVER_URL="${SERVER_URL//\'/\'\'}"
API_KEY="${API_KEY//\'/\'\'}"
{
elif config_has '.ApiKey' && config_has '.ImmichServerUrl'; then
bashio::log.info "Using single account configuration"
SRV="$(config_val '.ImmichServerUrl')"
KEY="$(config_val '.ApiKey')"
echo "Accounts:"
echo " - ImmichServerUrl: '${SERVER_URL}'"
echo " ApiKey: '${API_KEY}'"
} > "${SETTINGS_FILE}"
chmod 600 "${SETTINGS_FILE}"
bashio::log.info "Settings.yaml generated at ${SETTINGS_FILE}"
else
bashio::log.fatal "No accounts configured! Set either 'Accounts' list or both 'ApiKey' and 'ImmichServerUrl'"
exit 1
fi
echo " - ImmichServerUrl: '${SRV//\'/\'\'}'"
echo " ApiKey: '${KEY//\'/\'\'}'"
# Apply account-level env_vars to the single account
for key in "${!ACCOUNT_ENVS[@]}"; do
in_list "$key" " ImmichServerUrl ApiKey " && continue
yaml_kv " " "$key" "${ACCOUNT_ENVS[$key]}"
done
elif [ -n "${ACCOUNT_ENVS[ImmichServerUrl]:-}" ] && [ -n "${ACCOUNT_ENVS[ApiKey]:-}" ]; then
bashio::log.info "Using account configuration from env_vars"
echo "Accounts:"
echo " - ImmichServerUrl: '${ACCOUNT_ENVS[ImmichServerUrl]//\'/\'\'}'"
echo " ApiKey: '${ACCOUNT_ENVS[ApiKey]//\'/\'\'}'"
for key in "${!ACCOUNT_ENVS[@]}"; do
in_list "$key" " ImmichServerUrl ApiKey " && continue
yaml_kv " " "$key" "${ACCOUNT_ENVS[$key]}"
done
else
bashio::log.fatal "No accounts configured! Set either 'Accounts' list or both 'ApiKey' and 'ImmichServerUrl'"
exit 1
fi
} > "${SETTINGS_FILE}"
chmod 600 "${SETTINGS_FILE}"
bashio::log.info "Settings.yaml generated at ${SETTINGS_FILE}"
# Log contents (mask sensitive values)
bashio::log.info "--- Generated Settings.yaml ---"
sed -E 's/(ApiKey:).*/\1 *****/;s/(AuthenticationSecret:).*/\1 *****/' "${SETTINGS_FILE}" | while IFS= read -r line; do
bashio::log.info "$line"
done
bashio::log.info "-------------------------------"
export IMMICHFRAME_CONFIG_PATH=/config/Config
exec dotnet ImmichFrame.WebApi.dll