Compare commits

...

30 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
9ca9b54cb0 fix(nextcloud): use /share/nextcloud as default data directory and add data_location option
Agent-Logs-Url: https://github.com/alexbelgium/hassio-addons/sessions/3206d642-bf8c-49cc-b828-1ca2fe084ac7

Co-authored-by: alexbelgium <44178713+alexbelgium@users.noreply.github.com>
2026-05-29 13:00:20 +00:00
copilot-swe-agent[bot]
253909d46d Initial plan 2026-05-29 12:57:46 +00:00
Alexandre
69262733b8 Merge pull request #2743 from alexbelgium/copilot/review-birdnet-go-addon
Update birdnet-go README options
2026-05-28 20:37:53 +02:00
copilot-swe-agent[bot]
9a8ae515fa Update birdnet-go README options 2026-05-28 18:09:11 +00:00
Alexandre
59d85e2dd0 Use upstream 2026-05-28 20:07:00 +02:00
Alexandre
9eb6fdd681 Merge pull request #2742 from alexbelgium/claude/birdnet-homeassistant-review-T5oI4
birdnet-go: harden config init, auto-wire MQTT/MariaDB, trim ingress …
2026-05-28 19:42:45 +02:00
Claude
a4f6ab3b2f birdnet-go: don't abort init when default-config download fails
Removing /config/config.yaml after a failed first-boot curl left the
next yq read (.realtime.audio.export.path) trying to open a missing
file; under set -e that aborts the entire cont-init script, so the
addon would never get to seed its defaults or start BirdNET-Go.

Seed an empty YAML document ({}) instead. The existing "//=" defaults
block then populates output.sqlite.path, logging.file_output.*, and
the migration block writes realtime.audio.export.path. Result: an
offline first boot now produces a valid minimal config.yaml and the
container starts cleanly.

Also harden the yq read with "// """ so a freshly seeded "{}" doc
returns an empty string (caught by the existing :-DEFAULT fallback)
rather than the literal string "null".
2026-05-28 17:24:11 +00:00
Claude
854f90cbe8 birdnet-go: invert MQTT/MariaDB auto-config to opt-in
Replace mqtt_disable / mariadb_disable (opt-out, default-on) with
mqtt_auto_config / mariadb_auto_config (opt-in, default-off). When the
HA addon is detected but the option is off, still log the broker /
database credentials and a hint pointing the user at the option — so
discoverability stays the same without surprise config rewrites.
2026-05-28 17:21:12 +00:00
Claude
2087da7f18 birdnet-go: harden config init, auto-wire MQTT/MariaDB, trim ingress proxy
Bugs fixed in 01-structure.sh:
- Database backup created during BIRDSONGS_FOLDER migration was written
  to the script's CWD instead of /config, and the restore path was
  recomputed with a fresh timestamp — so any second-boundary crossing
  between backup and restore left the user unable to recover. Backup
  path is now absolute and reused for restore.
- Path inputs are validated against [A-Za-z0-9._/-]+ before being
  interpolated into the SQL UPDATE statement.
- Default-config download tolerates network failure instead of leaving
  an empty config.yaml behind.
- output.sqlite.path and logging.file_output.* are now seeded with the
  "set-if-missing" idiom (`//=`) so user edits to config.yaml survive
  restarts. (Breaking: addon options for log rotation now only seed
  defaults on first run.)
- Path normalization centralized; trailing-slash juggling removed.

UX upgrades:
- 33-mqtt.sh now auto-configures realtime.mqtt.* in config.yaml from
  the HA Mosquitto addon (with new mqtt_disable opt-out option).
- 33-mariadb.sh now auto-switches output.mysql.* to the HA MariaDB
  addon and disables SQLite (with mariadb_disable opt-out option).

Cleanup:
- Dockerfile: upstream entrypoint sed-patch now warns (not silently
  succeeds) when the target pattern is missing in a new nightly.
- Removed dead nginx upstream.conf pointing at unused port 8096.
- Trimmed redundant nginx HTML-attribute sub_filters; upstream
  birdnet-go handles those itself via X-Ingress-Path. JS string
  rewrites kept since the upstream HTML rewriter does not touch JS.
  (Breaking UI-side if upstream regresses — see CHANGELOG.)
2026-05-28 17:01:42 +00:00
Alexandre
b6560dfda7 Merge pull request #2741 from alexbelgium/copilot/fix-environment-variables-issue
Fix cron jobs not running in Firefly III Data Importer addon
2026-05-28 11:20:05 +02:00
copilot-swe-agent[bot]
3ad1b40ecf Run cron artisan import as www-data to prevent permission conflicts 2026-05-28 09:19:15 +00:00
copilot-swe-agent[bot]
92dbc30410 Bump fireflyiii_data_importer to 2.3.2-5 and update changelog 2026-05-28 09:09:37 +00:00
copilot-swe-agent[bot]
e22b44b5ec Fix cron jobs not running in Firefly III Data Importer addon
- Change cronupdate shebang from bashio to /bin/bash (cron PATH lacks bashio)
- Remove bashio API calls from cron script (no Supervisor access in cron)
- Source /.env in cron script to load all env_vars from 00-global_var.sh
- Persist SILENT_MODE to /etc/environment for cron access
- Remove destructive `sed 's|root|www-data|g'` on /etc/crontab
- Fix /etc/environment permissions from 600 to 644 for cron readability
2026-05-28 08:31:12 +00:00
copilot-swe-agent[bot]
b947226ac9 Initial plan 2026-05-28 08:27:48 +00:00
github-actions
e5d8f0d501 GitHub bot: changelog [nobuild] 2026-05-28 05:15:21 +00:00
Alexandre
c111c4983b Update config.yaml 2026-05-28 07:09:15 +02:00
Alexandre
5ec100b11d Update updater.json 2026-05-28 07:08:59 +02:00
github-actions
a350dc8680 GitHub bot: changelog [nobuild] 2026-05-27 19:38:28 +00:00
Alexandre
aae8b1cee6 Merge pull request #2740 from ToledoEM/manyfold
version bump Manyfold3D to 0.142.0
2026-05-27 21:36:27 +02:00
ToledoEM
5dbd8b05a5 version bump to 0.142.0 2026-05-27 18:51:00 +01:00
Alexandre
9151d3bc8a Clean logs
birdnet-go: quiet startup logs (chmod, JACK, OSS, dsnoop)
2026-05-27 10:29:18 +02:00
Alexandre
0248c95e59 Merge branch 'master' into claude/birdnet-go-startup-errors-ttace 2026-05-27 10:28:12 +02:00
Claude
78b47f5355 birdnet-go: ship ALSA overrides at /root/.asoundrc
/etc/asound.conf is read-only in the addon environment, so both the
shipped overrides and the user-supplied override are now written to
/root/.asoundrc (the app runs as root with HOME=/root). ALSA loads
~/.asoundrc as an additive layer on top of the system config, so the
override behavior is unchanged.
2026-05-27 08:26:36 +00:00
Alexandre
8f423ad2f4 Merge pull request #2737 from alexbelgium/copilot/birdnet-go-fix-log-storage nobuild
feat(birdnet-go): add log rotation options to prevent unbounded log growth
2026-05-27 10:21:58 +02:00
Alexandre
733134ed5d Update CHANGELOG.md 2026-05-27 10:15:13 +02:00
Alexandre
d6de19315d Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-27 07:27:14 +02:00
copilot-swe-agent[bot]
71bb8b5130 feat(birdnet-go): add LOG_MAX_SIZE_MB and LOG_MAX_AGE_DAYS options to manage log storage
Add addon options to control birdnet-go log file rotation:
- LOG_MAX_SIZE_MB (default: 50): maximum size per log file before rotation
- LOG_MAX_AGE_DAYS (default: 7): maximum days to retain old log files

On startup, the addon:
1. Configures birdnet-go's logging.file_output settings in config.yaml
2. Sets max_rotated_files to 3 and enables compression
3. Trims existing log files exceeding the configured age

Fixes #1922
2026-05-26 19:47:38 +00:00
Claude
4975eca7c2 birdnet-go: allow user-supplied /config/asound.conf override
Advanced users who legitimately need JACK, a custom dsnoop chain, or any
other ALSA setup can drop their own asound.conf into the addon config
folder. The cont-init script copies it over /etc/asound.conf before
launching the app, replacing the addon-shipped defaults.
2026-05-26 19:47:05 +00:00
copilot-swe-agent[bot]
e09e2afb2c Initial plan 2026-05-26 19:45:00 +00:00
Claude
05cbe751d5 birdnet-go: suppress noisy startup errors
- Patch upstream entrypoint via sed so chmod on the read-only /dev/snd
  mount no longer prints "Read-only file system" lines.
- Add /etc/asound.conf overriding the JACK, OSS, dsp, and dsnoop PCM
  plugins to type "null" with hint.show off. This hides them from
  snd_device_name_hint(), so miniaudio's device enumeration no longer
  probes them at launch and the corresponding libjack/pcm_oss/pcm_dsnoop
  errors disappear.
2026-05-26 16:23:20 +00:00
24 changed files with 369 additions and 99 deletions

View File

@@ -1,5 +1,23 @@
## nightly-20260525-3 (28-05-2026)
- New `mqtt_auto_config` addon option (default `false`). When `true` and the Home Assistant MQTT addon is active, `realtime.mqtt.{enabled,broker,username,password}` are written directly to `config.yaml` on every restart. When `false` but Mosquitto is detected, the addon still logs the broker details and reminds you about the option — nothing is written.
- New `mariadb_auto_config` addon option (default `false`). When `true` and the Home Assistant MariaDB addon is active, `output.mysql.*` is filled in and `output.sqlite.enabled` is set to `false`. When `false` but MariaDB is detected, the addon logs the credentials and reminds you about the option.
- **Breaking**: `output.sqlite.path` and `logging.file_output.*` are now seeded only when missing from `config.yaml` (previously overwritten every restart). Values changed through the BirdNET-Go UI or by hand-editing `config.yaml` now survive container restarts. If you relied on `LOG_MAX_SIZE_MB` / `LOG_MAX_AGE_DAYS` addon options to override an existing setting in `config.yaml`, remove the existing key from `config.yaml` or edit it directly — the option will only be applied on first run.
- **Breaking (UI only)**: The nginx ingress reverse-proxy no longer rewrites HTML `href`/`src`/`action` attributes; upstream BirdNET-Go handles those itself via `X-Ingress-Path`. JavaScript string-literal rewrites are unchanged. Please file an issue if you see broken images, links, or forms in the ingress UI after upgrade.
- Fix database-migration restore: the timestamped backup created during a `BIRDSONGS_FOLDER` change was being written to the script's working directory and looked up under a fresh timestamp on restore, so a SQL failure left the user unable to recover. Backup path is now absolute and reused for restore.
- Harden the `BIRDSONGS_FOLDER` SQL/YAML path substitution: paths containing characters outside `[A-Za-z0-9._/-]` are now rejected up front instead of being interpolated raw into the SQL UPDATE statement.
- Tolerate a missing internet connection on first boot: if the default `config.yaml` cannot be downloaded from GitHub, the init script now seeds an empty YAML document so the addon-defaults block populates a usable config (rather than aborting the script on the next `yq` call under `set -e`).
- Warn (without failing the build) if the upstream `entrypoint.sh` patch target drifts in a new nightly.
- Remove a dead nginx upstream definition that pointed at an unused port.
## nightly-20260525-2 (26-05-2026)
- Suppress noisy startup logs: silence `chmod /dev/snd` errors on the read-only HA mount, and hide unavailable ALSA plugins (JACK, OSS, dsnoop) from device enumeration so libjack and pcm_oss/dsnoop probes no longer print at launch. ALSA overrides are written to `/root/.asoundrc` (since `/etc/asound.conf` is read-only in this environment).
- Allow advanced users to override the ALSA config by dropping a custom `asound.conf` into the addon config folder.
- Add LOG_MAX_SIZE_MB and LOG_MAX_AGE_DAYS addon options to manage log storage size
- Automatically trim log files exceeding configured age on startup
## nightly-20260525 (26-05-2026)
- Minor bugs fixed
## nightly-20260511-414-2 (22-05-2026)
- Minor bugs fixed

View File

@@ -36,6 +36,19 @@ ENV S6_CMD_WAIT_FOR_SERVICES=1 \
COPY rootfs/ /
RUN find . -type f \( -name "*.sh" -o -name "run" -o -name "finish" \) -print -exec chmod +x {} \;
# Silence "chmod: Read-only file system" noise from upstream entrypoint:
# Home Assistant mounts /dev/snd read-only, so the chmod is a no-op and the
# stderr output is just noise. The "|| true" already absorbs the exit code.
# Warn (without failing the build) if the upstream pattern drifts so we notice
# in CI logs and can update the patch.
RUN if [ -f /usr/bin/entrypoint.sh ]; then \
if grep -q 'chmod -R a+rw /dev/snd || true' /usr/bin/entrypoint.sh; then \
sed -i 's#chmod -R a+rw /dev/snd || true#chmod -R a+rw /dev/snd 2>/dev/null || true#' /usr/bin/entrypoint.sh; \
else \
echo "WARN: upstream entrypoint.sh /dev/snd chmod pattern not found; nightly drift?" >&2; \
fi; \
fi
# Uses /bin for compatibility purposes
# hadolint ignore=DL4005
RUN if [ ! -f /bin/sh ] && [ -f /usr/bin/sh ]; then ln -s /usr/bin/sh /bin/sh; fi && \
@@ -124,12 +137,3 @@ RUN \
awk '/http \{/{print; print "map $http_user_agent $dontlog {\n default 0;\n \"~*HealthCheck\" 1;\n}\naccess_log /var/log/nginx/access.log combined if=$dontlog;"; next}1' /etc/nginx/nginx.conf > /etc/nginx/nginx.conf.new && \
mv /etc/nginx/nginx.conf.new /etc/nginx/nginx.conf; \
fi
ENV HEALTH_PORT="80" \
HEALTH_URL=""
HEALTHCHECK \
--interval=5s \
--retries=5 \
--start-period=30s \
--timeout=25s \
CMD curl -A "HealthCheck: Docker/1.0" -s -f "http://127.0.0.1:${HEALTH_PORT}${HEALTH_URL}" &>/dev/null || exit 1

View File

@@ -46,9 +46,14 @@ Options can be configured through three ways :
- Addon options
```yaml
ALSA_CARD : number of the card (0 or 1 usually), see https://github.com/tphakala/birdnet-go/blob/main/doc/installation.md#deciding-alsa_card-value
TZ: Etc/UTC specify a timezone to use, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
COMMAND : realtime --rtsp url # allows to provide arguments to birdnet-go
BIRDSONGS_FOLDER: /config/clips # where audio clips are stored (can be on a mounted drive)
LOG_MAX_SIZE_MB: 50 # max log file size before rotation
LOG_MAX_AGE_DAYS: 7 # max log retention in days
homeassistant_microphone: false # when true, force audio source to "default" (HA microphone)
env_vars: [] # extra environment variables to pass to the container
TZ: Etc/UTC # timezone, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
mqtt_auto_config: false # set true to auto-wire the Home Assistant MQTT addon into config.yaml
mariadb_auto_config: false # set true to auto-wire the Home Assistant MariaDB addon into config.yaml (also disables SQLite)
```
- Config.yaml
@@ -57,6 +62,14 @@ Additional variables can be configured using the config.yaml file found in /conf
- Config_env.yaml
Additional environment variables can be configured there
### MQTT and MariaDB auto-configuration (opt-in)
If the Home Assistant **MQTT** addon is installed and running and you set `mqtt_auto_config: true` in the addon options, the addon writes the HA Mosquitto credentials directly into BirdNET-Go's `config.yaml` on every startup: `realtime.mqtt.enabled`, `broker`, `username`, and `password` are populated, and the topic defaults to `birdnet`. When the option is `false` (the default), the addon still logs the broker details and reminds you about the option whenever Mosquitto is detected — nothing is written.
If the Home Assistant **MariaDB** addon is installed and running and you set `mariadb_auto_config: true`, the addon writes the HA credentials into `output.mysql.*` and sets `output.sqlite.enabled` to `false` (database name `birdnet`, created on first connect). When the option is `false` (the default), the addon only logs the credentials so you can configure them manually.
The addon also seeds `output.sqlite.path` and `logging.file_output.*` defaults only when those keys are missing from `config.yaml`, so values you change through the BirdNET-Go UI now survive container restarts.
### Mounting Drives
This addon supports mounting both local drives and remote SMB shares:
@@ -159,4 +172,3 @@ Create an issue on github
![illustration](https://raw.githubusercontent.com/tphakala/birdnet-go/main/doc/BirdNET-Go-dashboard.webp)

View File

@@ -86,7 +86,11 @@ name: Birdnet-go
options:
env_vars: []
BIRDSONGS_FOLDER: /config/clips
LOG_MAX_SIZE_MB: 50
LOG_MAX_AGE_DAYS: 7
homeassistant_microphone: false
mqtt_auto_config: false
mariadb_auto_config: false
panel_admin: false
panel_icon: mdi:bird
ports:
@@ -104,12 +108,16 @@ schema:
- name: match(^[A-Za-z0-9_]+$)
value: str?
BIRDSONGS_FOLDER: str?
LOG_MAX_SIZE_MB: int(1,1000)?
LOG_MAX_AGE_DAYS: int(1,365)?
TZ: str?
cifsdomain: str?
cifspassword: str?
cifsusername: str?
homeassistant_microphone: bool?
localdisks: str?
mariadb_auto_config: bool?
mqtt_auto_config: bool?
networkdisks: str?
services:
- mysql:want
@@ -118,4 +126,4 @@ slug: birdnet-go
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/birdnet-go
usb: true
version: "nightly-20260525"
version: "nightly-20260525-3"

View File

@@ -3,12 +3,41 @@
set -e
# Default Variables
DEFAULT_BIRDSONGS_FOLDER="/data/clips/"
DEFAULT_BIRDSONGS_FOLDER="/data/clips"
CONFIG_LOCATION="/config/config.yaml"
# Strip trailing slashes; canonical internal form has none.
normalize_path() {
local p="$1"
while [[ "$p" == */ && "$p" != "/" ]]; do
p="${p%/}"
done
printf '%s' "$p"
}
# Reject paths containing characters that would break the SQL/YAML literals
# we substitute into below. We deliberately allow only "safe" filename chars.
validate_safe_path() {
local p="$1"
if [[ ! "$p" =~ ^[A-Za-z0-9._/-]+$ ]]; then
bashio::log.fatal "Refusing unsafe path: '$p' (only [A-Za-z0-9._/-] allowed)"
exit 1
fi
}
if [ ! -f "$CONFIG_LOCATION" ]; then
bashio::log.warning "There is no config.yaml yet in the config folder, downloading a default one. Please customize"
curl -L -s -S https://raw.githubusercontent.com/tphakala/birdnet-go/refs/heads/main/internal/conf/config.yaml -o "$CONFIG_LOCATION"
# Network may be unreachable on first boot. If the download fails, seed
# an empty YAML document so the yq reads/writes below succeed and the
# default-value seeding logic later in this script populates a usable
# config. (We can't remove the file and continue — subsequent yq calls
# under set -e would abort the init script.)
if ! curl -fL -s -S \
https://raw.githubusercontent.com/tphakala/birdnet-go/refs/heads/main/internal/conf/config.yaml \
-o "$CONFIG_LOCATION"; then
bashio::log.warning "Could not download default config.yaml; seeding an empty document so addon defaults can populate it"
echo '{}' > "$CONFIG_LOCATION"
fi
fi
#################
@@ -22,20 +51,24 @@ fi
######################
# Birdsongs Location
######################
CURRENT_BIRDSONGS_FOLDER="clips/"
# Read the current folder from config files
CURRENT_BIRDSONGS_FOLDER="$(yq '.realtime.audio.export.path' "$CONFIG_LOCATION" | tr -d '\"')"
# Read the current folder from config.yaml; "// """ collapses both missing
# keys and explicit nulls (e.g. in a freshly seeded "{}" doc) to an empty
# string so the ${VAR:-DEFAULT} fallback below kicks in.
CURRENT_BIRDSONGS_FOLDER="$(yq -r '.realtime.audio.export.path // ""' "$CONFIG_LOCATION")"
CURRENT_BIRDSONGS_FOLDER="${CURRENT_BIRDSONGS_FOLDER:-$DEFAULT_BIRDSONGS_FOLDER}"
# Adjust default path if it matches the default string
if [[ "$CURRENT_BIRDSONGS_FOLDER" == "clips/" ]]; then
# Treat the upstream-shipped relative "clips/" as the legacy default.
if [[ "$CURRENT_BIRDSONGS_FOLDER" == "clips" || "$CURRENT_BIRDSONGS_FOLDER" == "clips/" ]]; then
CURRENT_BIRDSONGS_FOLDER="$DEFAULT_BIRDSONGS_FOLDER"
fi
CURRENT_BIRDSONGS_FOLDER="$(normalize_path "$CURRENT_BIRDSONGS_FOLDER")"
# Set the new birdsongs folder
# Set the new birdsongs folder from addon options (default: relative "clips").
BIRDSONGS_FOLDER="$(bashio::config "BIRDSONGS_FOLDER")"
BIRDSONGS_FOLDER="${BIRDSONGS_FOLDER:-clips/}"
BIRDSONGS_FOLDER="${BIRDSONGS_FOLDER%/}" # Remove trailing slash if present
BIRDSONGS_FOLDER="$(normalize_path "${BIRDSONGS_FOLDER:-clips}")"
validate_safe_path "$BIRDSONGS_FOLDER"
validate_safe_path "$CURRENT_BIRDSONGS_FOLDER"
if [[ ! "$BIRDSONGS_FOLDER" == /* ]]; then
if [ ! -d "/config/$BIRDSONGS_FOLDER" ]; then
mkdir -p "/config/$BIRDSONGS_FOLDER"
@@ -52,42 +85,43 @@ fi
bashio::log.info "... audio clips saved to $BIRDSONGS_FOLDER according to addon options"
# Migrate data if the folder has changed
if [[ "${CURRENT_BIRDSONGS_FOLDER%/}" != "${BIRDSONGS_FOLDER%/}" ]]; then
if [[ "$CURRENT_BIRDSONGS_FOLDER" != "$BIRDSONGS_FOLDER" ]]; then
bashio::log.warning "Birdsongs folder changed from $CURRENT_BIRDSONGS_FOLDER to $BIRDSONGS_FOLDER"
# Update config files with the new birdsongs folder path
yq -i -y ".realtime.audio.export.path = \"$BIRDSONGS_FOLDER/\"" "$CONFIG_LOCATION"
# Update config.yaml with the new birdsongs folder path (trailing slash
# restored only at the boundary, since birdnet-go expects it).
yq -i -y ".realtime.audio.export.path = \"${BIRDSONGS_FOLDER}/\"" "$CONFIG_LOCATION"
# Move files only if sqlite paths changed
if [[ -d "$CURRENT_BIRDSONGS_FOLDER" && "$(ls -A "$CURRENT_BIRDSONGS_FOLDER")" ]]; then
bashio::log.warning "Migrating files from $CURRENT_BIRDSONGS_FOLDER to $BIRDSONGS_FOLDER"
cp -rnf "$CURRENT_BIRDSONGS_FOLDER"/* "$BIRDSONGS_FOLDER"/
mv "${CURRENT_BIRDSONGS_FOLDER%/}" "${CURRENT_BIRDSONGS_FOLDER%/}_migrated"
mv "$CURRENT_BIRDSONGS_FOLDER" "${CURRENT_BIRDSONGS_FOLDER}_migrated"
fi
# Adapt the database
if [ -f /config/birdnet.db ]; then
# Prepare
backup="$(date +%Y%m%d_%H%M%S)"
bashio::log.warning "Modifying database paths from $CURRENT_BIRDSONGS_FOLDER to $BIRDSONGS_FOLDER. A backup named birdnet.db_$backup will be created before"
BACKUP_FILE="/config/birdnet.db_${backup}"
bashio::log.warning "Modifying database paths from $CURRENT_BIRDSONGS_FOLDER to $BIRDSONGS_FOLDER. A backup will be created at ${BACKUP_FILE}"
# Create backup
if ! cp /config/birdnet.db "birdnet.db_$backup"; then
# Create backup at the absolute path we'll restore from on failure.
if ! cp /config/birdnet.db "$BACKUP_FILE"; then
bashio::log.error "Failed to create a backup of the database. Aborting path modification."
exit 1
fi
# Execute the query using sqlite3
SQL_QUERY="UPDATE notes SET clip_name = '${BIRDSONGS_FOLDER%/}/' || substr(clip_name, length('${CURRENT_BIRDSONGS_FOLDER%/}/') + 1) WHERE clip_name LIKE '${CURRENT_BIRDSONGS_FOLDER%/}/%';"
# Paths were validated above against [A-Za-z0-9._/-]+ so quote
# escaping in the SQL literal is not a concern.
SQL_QUERY="UPDATE notes SET clip_name = '${BIRDSONGS_FOLDER}/' || substr(clip_name, length('${CURRENT_BIRDSONGS_FOLDER}/') + 1) WHERE clip_name LIKE '${CURRENT_BIRDSONGS_FOLDER}/%';"
if ! sqlite3 /config/birdnet.db "$SQL_QUERY"; then
bashio::log.warning "An error occurred while updating the paths. The database backup will be restored."
BACKUP_FILE="/config/birdnet.db_$(date +%Y%m%d_%H%M%S)" # Make sure this matches the earlier backup filename
if [ -f "$BACKUP_FILE" ]; then
mv "$BACKUP_FILE" /config/birdnet.db
bashio::log.info "The database backup has been restored."
else
bashio::log.error "Backup file not found! Manual intervention required."
bashio::log.error "Backup file $BACKUP_FILE not found! Manual intervention required."
fi
else
echo "Paths have been successfully updated."
bashio::log.info "Paths have been successfully updated."
fi
fi
fi
@@ -95,8 +129,33 @@ fi
####################
# Correct Defaults
####################
bashio::log.info "Correcting configuration for defaults"
# Seed addon-specific defaults only if the user has not set them in
# config.yaml. The "//=" form leaves any user-edited value alone, so
# changes made via the BirdNET-Go UI or by hand-editing /config/config.yaml
# survive container restarts.
bashio::log.info "Seeding default configuration values (only if missing)"
# Update database location in config files
yq -i -y ".output.sqlite.path = \"/config/birdnet.db\"" "$CONFIG_LOCATION"
bashio::log.info "... database is located in /config/birdnet.db"
yq -i -y '.output.sqlite.path //= "/config/birdnet.db"' "$CONFIG_LOCATION"
####################
# Log Management
####################
LOG_MAX_SIZE_MB="$(bashio::config "LOG_MAX_SIZE_MB")"
LOG_MAX_SIZE_MB="${LOG_MAX_SIZE_MB:-50}"
LOG_MAX_AGE_DAYS="$(bashio::config "LOG_MAX_AGE_DAYS")"
LOG_MAX_AGE_DAYS="${LOG_MAX_AGE_DAYS:-7}"
bashio::log.info "Seeding default log rotation: max ${LOG_MAX_SIZE_MB}MB per file, max ${LOG_MAX_AGE_DAYS} days retention (only applied if not already set)"
# Seed log-rotation defaults; do not clobber user-edited values.
yq -i -y ".logging.file_output.max_size //= ${LOG_MAX_SIZE_MB}" "$CONFIG_LOCATION"
yq -i -y ".logging.file_output.max_age //= ${LOG_MAX_AGE_DAYS}" "$CONFIG_LOCATION"
yq -i -y '.logging.file_output.max_rotated_files //= 3' "$CONFIG_LOCATION"
yq -i -y '.logging.file_output.compress //= true' "$CONFIG_LOCATION"
# Trim existing log files that exceed the configured max age
LOG_DIR="/config/logs"
if [ -d "$LOG_DIR" ]; then
bashio::log.info "Trimming log files older than ${LOG_MAX_AGE_DAYS} days in ${LOG_DIR}"
find "$LOG_DIR" -type f -name "*.log*" -mtime +"$LOG_MAX_AGE_DAYS" -delete 2>/dev/null || true
fi

View File

@@ -2,15 +2,64 @@
# shellcheck shell=bash
set -e
# Gives mariadb information
# When the Home Assistant MariaDB addon is active, optionally wire its
# credentials directly into BirdNET-Go's config.yaml. Upstream reads MySQL
# settings only from YAML (no env-var overrides exist), so this is the only
# way to auto-configure them. The behaviour is opt-in via the
# mariadb_auto_config addon option. When the option is off but MariaDB is
# detected, we log a one-shot hint pointing users at the option.
if bashio::services.available 'mysql'; then
bashio::log.green "---"
bashio::log.yellow "MariaDB addon is active on your system! If you want to use it instead of sqlite, here are the informations to encode :"
bashio::log.blue "Database user : $(bashio::services "mysql" "username")"
bashio::log.blue "Database password : $(bashio::services "mysql" "password")"
bashio::log.blue "Database name : birdnet"
bashio::log.blue "Host-name : $(bashio::services "mysql" "host")"
bashio::log.blue "Port : $(bashio::services "mysql" "port")"
bashio::log.green "---"
CONFIG_LOCATION="/config/config.yaml"
MYSQL_DATABASE="birdnet"
if ! bashio::services.available 'mysql'; then
exit 0
fi
MYSQL_HOST="$(bashio::services 'mysql' 'host')"
MYSQL_PORT="$(bashio::services 'mysql' 'port')"
MYSQL_USER="$(bashio::services 'mysql' 'username')"
MYSQL_PASS="$(bashio::services 'mysql' 'password')"
if ! bashio::config.true 'mariadb_auto_config'; then
bashio::log.green "---"
bashio::log.yellow "Home Assistant MariaDB addon detected. Set 'mariadb_auto_config: true' in the addon options to wire it into BirdNET-Go automatically (and disable SQLite). Connection details:"
bashio::log.blue "Database user : ${MYSQL_USER}"
bashio::log.blue "Database password: ${MYSQL_PASS}"
bashio::log.blue "Database name : ${MYSQL_DATABASE}"
bashio::log.blue "Host-name : ${MYSQL_HOST}"
bashio::log.blue "Port : ${MYSQL_PORT}"
bashio::log.green "---"
exit 0
fi
if [ ! -f "$CONFIG_LOCATION" ]; then
bashio::log.warning "Skipping MariaDB auto-configuration: $CONFIG_LOCATION not found"
exit 0
fi
bashio::log.green "---"
bashio::log.blue "mariadb_auto_config enabled; writing Home Assistant MariaDB credentials into BirdNET-Go config and disabling SQLite"
bashio::log.blue "Host: ${MYSQL_HOST}:${MYSQL_PORT}"
bashio::log.blue "User: ${MYSQL_USER}"
bashio::log.blue "Database: ${MYSQL_DATABASE} (will be created by BirdNET-Go on first connect)"
bashio::log.green "---"
# Upstream config.go stores port as a string; pass it as such to match.
# $host / $port / etc. are jq/yq variables, not shell expansions — the
# single quotes around the filter are intentional.
# shellcheck disable=SC2016
yq -i -y \
--arg host "$MYSQL_HOST" \
--arg port "$MYSQL_PORT" \
--arg user "$MYSQL_USER" \
--arg pass "$MYSQL_PASS" \
--arg db "$MYSQL_DATABASE" \
'.output.mysql.enabled = true
| .output.mysql.host = $host
| .output.mysql.port = $port
| .output.mysql.username = $user
| .output.mysql.password = $pass
| .output.mysql.database = $db
| .output.sqlite.enabled = false' \
"$CONFIG_LOCATION"

View File

@@ -2,13 +2,56 @@
# shellcheck shell=bash
set -e
# Gives mqtt information
# When the Home Assistant MQTT addon is active, optionally wire its
# credentials directly into BirdNET-Go's config.yaml. Upstream reads MQTT
# settings only from YAML (no env-var overrides exist), so this is the only
# way to auto-configure them. The behaviour is opt-in via the
# mqtt_auto_config addon option. When the option is off but Mosquitto is
# detected, we log a one-shot hint pointing users at the option.
if bashio::services.available 'mqtt'; then
bashio::log.green "---"
bashio::log.yellow "MQTT addon is active on your system! Add the MQTT details below to the Birdnet-go config.yaml :"
bashio::log.blue "MQTT user : $(bashio::services "mqtt" "username")"
bashio::log.blue "MQTT password : $(bashio::services "mqtt" "password")"
bashio::log.blue "MQTT broker : tcp://$(bashio::services "mqtt" "host"):$(bashio::services "mqtt" "port")"
bashio::log.green "---"
CONFIG_LOCATION="/config/config.yaml"
if ! bashio::services.available 'mqtt'; then
exit 0
fi
MQTT_HOST="$(bashio::services 'mqtt' 'host')"
MQTT_PORT="$(bashio::services 'mqtt' 'port')"
MQTT_USER="$(bashio::services 'mqtt' 'username')"
MQTT_PASS="$(bashio::services 'mqtt' 'password')"
MQTT_BROKER="tcp://${MQTT_HOST}:${MQTT_PORT}"
if ! bashio::config.true 'mqtt_auto_config'; then
bashio::log.green "---"
bashio::log.yellow "Home Assistant MQTT addon detected. Set 'mqtt_auto_config: true' in the addon options to wire it into BirdNET-Go automatically. Connection details:"
bashio::log.blue "MQTT user : ${MQTT_USER}"
bashio::log.blue "MQTT password: ${MQTT_PASS}"
bashio::log.blue "MQTT broker : ${MQTT_BROKER}"
bashio::log.green "---"
exit 0
fi
if [ ! -f "$CONFIG_LOCATION" ]; then
bashio::log.warning "Skipping MQTT auto-configuration: $CONFIG_LOCATION not found"
exit 0
fi
bashio::log.green "---"
bashio::log.blue "mqtt_auto_config enabled; writing Home Assistant MQTT credentials into BirdNET-Go config"
bashio::log.blue "Broker: ${MQTT_BROKER}"
bashio::log.blue "User: ${MQTT_USER}"
bashio::log.green "---"
# $broker / $user / $pass / "birdnet" are jq/yq variables and literals,
# not shell expansions, so the single quotes are intentional.
# shellcheck disable=SC2016
yq -i -y \
--arg broker "$MQTT_BROKER" \
--arg user "$MQTT_USER" \
--arg pass "$MQTT_PASS" \
'.realtime.mqtt.enabled = true
| .realtime.mqtt.broker = $broker
| .realtime.mqtt.username = $user
| .realtime.mqtt.password = $pass
| .realtime.mqtt.topic //= "birdnet"' \
"$CONFIG_LOCATION"

View File

@@ -8,6 +8,20 @@ set -e
echo " "
# Allow advanced users to supply their own ALSA config (e.g. to enable JACK
# or a custom dsnoop chain) by dropping asound.conf into the addon config
# folder. Written to /root/.asoundrc because /etc/asound.conf is read-only.
if [ -f /config/asound.conf ]; then
if [ -r /config/asound.conf ]; then
bashio::log.info "Using user-provided /config/asound.conf, overriding addon defaults"
if ! cp /config/asound.conf /root/.asoundrc; then
bashio::log.warning "Failed to copy /config/asound.conf; continuing with bundled /root/.asoundrc defaults"
fi
else
bashio::log.warning "/config/asound.conf exists but is not readable; continuing with bundled /root/.asoundrc defaults"
fi
fi
# Check if alsa_card is provided
CONFIG_LOCATION="/config/config.yaml"
if bashio::config.true "homeassistant_microphone"; then

View File

@@ -1,3 +0,0 @@
upstream backend {
server 127.0.0.1:8096;
}

View File

@@ -76,7 +76,6 @@ http {
}
include /etc/nginx/includes/resolver.conf;
include /etc/nginx/includes/upstream.conf;
include /etc/nginx/servers/*.conf;
}

View File

@@ -21,29 +21,25 @@ server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Tell BirdNET-Go its proxy prefix (NEW — required)
# Tell BirdNET-Go its proxy prefix. Upstream honours X-Ingress-Path
# in internal/api/server.go and rewrites HTML href/src/action
# attributes itself, so we no longer duplicate that work here.
proxy_set_header X-Ingress-Path %%ingress_entry%%;
# Prevent timeouts
proxy_read_timeout 86400;
proxy_send_timeout 86400;
# sub_filter setup
# sub_filter setup: keep gzip off and the type filter wide so JS gets
# touched too (the upstream HTML rewriter does not look inside JS).
proxy_set_header Accept-Encoding "";
sub_filter_once off;
sub_filter_types *;
# HTML attribute rewrites
sub_filter href=\"/ href=\"%%ingress_entry%%/;
sub_filter src=\"/ src=\"%%ingress_entry%%/;
sub_filter src=\"'/ src=\"'%%ingress_entry%%/;
sub_filter action=\"/ action=\"%%ingress_entry%%/;
# JavaScript string rewrites (needed for Vite dynamic imports)
# JS string-literal rewrites — paths embedded in JS code are not
# touched by upstream's HTML rewriter, so we patch them here.
sub_filter EventSource('/ EventSource('%%ingress_entry%%/;
sub_filter fetch('/ fetch('%%ingress_entry%%/;
# Backtick template literal rewrites
sub_filter `/api/v `%%ingress_entry%%/api/v;
sub_filter "'/api/v" "'%%ingress_entry%%/api/v";
sub_filter \"/api/v \"%%ingress_entry%%/api/v;
@@ -53,8 +49,6 @@ server {
sub_filter `/asset `%%ingress_entry%%/asset;
sub_filter "'/asset" "'%%ingress_entry%%/asset";
sub_filter \"/asset \"%%ingress_entry%%/asset;
# Streaming/EventSource fix
sub_filter window.location.origin} window.location.origin}%%ingress_entry%%;
}
}

View File

@@ -0,0 +1,35 @@
# Home Assistant addon: birdnet-go
#
# Shipped at /root/.asoundrc because /etc/asound.conf is read-only in this
# environment. ALSA loads ~/.asoundrc as an additive layer on top of the
# system config, so the overrides below take effect for the birdnet-go process
# (which runs as root, HOME=/root).
#
# Replace ALSA PCM plugins whose backends are not available in the addon
# container (JACK server, OSS /dev/dsp) with type "null" and hide them from
# snd_device_name_hint(). Without this, miniaudio's capture-device enumeration
# probes every PCM hint at startup, triggering noisy errors like:
# - "Cannot connect to server socket" / "jack server is not running" (libjack)
# - "ALSA lib pcm_oss.c: Cannot open device /dev/dsp"
# - "ALSA lib pcm_dsnoop.c: unable to open slave"
# BirdNET-Go itself never opens these PCMs; only the enumeration probe does.
pcm.!jack {
type null
hint.show off
}
pcm.!oss {
type null
hint.show off
}
pcm.!dsp {
type null
hint.show off
}
pcm.!dsnoop {
type null
hint.show off
}

View File

@@ -1,3 +1,5 @@
## 0.7.3 (28-05-2026)
- Minor bugs fixed
## 0.7.1 (2026-05-22)
- Update to latest version from Suncuss/BirdNET-PiPy (changelog : https://github.com/Suncuss/BirdNET-PiPy/releases)

View File

@@ -96,4 +96,4 @@ schema:
ssl: bool?
slug: birdnet-pipy
url: https://github.com/alexbelgium/hassio-addons/tree/master/birdnet-pipy
version: "0.7.1"
version: "0.7.3"

View File

@@ -1,8 +1,8 @@
{
"last_update": "2026-05-22",
"last_update": "2026-05-29",
"repository": "alexbelgium/hassio-addons",
"slug": "birdnet-pipy",
"source": "github",
"upstream_repo": "Suncuss/BirdNET-PiPy",
"upstream_version": "0.7.1"
"upstream_version": "0.7.3"
}

View File

@@ -1,3 +1,6 @@
## 2.3.2-5 (28-05-2026)
- Fix cron jobs not running (wrong shebang, missing env vars, broken crontab)
## 2.3.2-4 (18-05-2026)
- Minor bugs fixed
## 2.3.2-3 (18-05-2026)

View File

@@ -101,5 +101,5 @@ schema:
slug: fireflyiii_data_importer
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "2.3.2-4"
version: "2.3.2-5"
webui: "[PROTO:ssl]://[HOST]:[PORT:8080]"

View File

@@ -27,6 +27,10 @@ export CAN_POST_FILES="$(bashio::config "CAN_POST_FILES")"
export CAN_POST_AUTOIMPORT="$(bashio::config "CAN_POST_AUTOIMPORT")"
# Persist variables to /etc/environment for cron jobs
SILENT_MODE="false"
if bashio::config.true 'silent'; then
SILENT_MODE="true"
fi
{
[ -n "$JSON_CONFIGURATION_DIR" ] && echo "JSON_CONFIGURATION_DIR=\"$JSON_CONFIGURATION_DIR\""
echo "CONFIG_LOCATION=\"$CONFIGSOURCE\""
@@ -35,8 +39,9 @@ export CAN_POST_AUTOIMPORT="$(bashio::config "CAN_POST_AUTOIMPORT")"
echo "AUTO_IMPORT_SECRET=\"$AUTO_IMPORT_SECRET\""
echo "CAN_POST_FILES=\"$CAN_POST_FILES\""
echo "CAN_POST_AUTOIMPORT=\"$CAN_POST_AUTOIMPORT\""
echo "SILENT_MODE=\"$SILENT_MODE\""
} >> /etc/environment
chmod 600 /etc/environment
chmod 644 /etc/environment
################
# CRON OPTIONS #
@@ -54,9 +59,6 @@ if bashio::config.has_value 'Updates'; then
cp /templates/cronupdate /etc/cron."${FREQUENCY}"/
chmod 755 /etc/cron."${FREQUENCY}"/cronupdate
# Sets cron to run with www-data user
sed -i 's|root|www-data|g' /etc/crontab
# Starts cron
service cron start

View File

@@ -1,20 +1,22 @@
#!/usr/bin/env bashio
#!/bin/bash
# shellcheck shell=bash
set -e
# Source environment variables for cron context
# shellcheck disable=SC1091
if [ -f /etc/environment ]; then set -a; . /etc/environment; set +a; fi
# shellcheck disable=SC1091
if [ -f /.env ]; then set -a; . /.env; set +a; fi
# Use persisted value instead of calling bashio::config (www-data may lack API access)
CONFIGSOURCE="${CONFIG_LOCATION}"
(
bashio::log.info "Running update according to defined schedule. Files located in $CONFIGSOURCE/import_files will be imported. If /config, it is accessible in the folder /addon_configs/xxx-firefly_data_importer when using the Filebrowser addon"
if bashio::config.true 'silent'; then
bashio::log.warning "Silent mode activated. Only errors will be shown. Please disable in addon options if you need to debug"
/usr/local/bin/php /var/www/html/artisan importer:auto-import "$CONFIGSOURCE/import_files" >/dev/null
echo "[INFO] Running update according to defined schedule. Files located in $CONFIGSOURCE/import_files will be imported."
if [ "${SILENT_MODE}" = "true" ]; then
echo "[WARNING] Silent mode activated. Only errors will be shown. Please disable in addon options if you need to debug"
sudo -Eu www-data /usr/local/bin/php /var/www/html/artisan importer:auto-import "$CONFIGSOURCE/import_files" >/dev/null
else
/usr/local/bin/php /var/www/html/artisan importer:auto-import "$CONFIGSOURCE/import_files"
sudo -Eu www-data /usr/local/bin/php /var/www/html/artisan importer:auto-import "$CONFIGSOURCE/import_files"
fi
) &>/proc/1/fd/1

View File

@@ -1,7 +1,17 @@
## 0.140.1 (18-05-2026)
## 0.142.0 (27-05-2026)
- Minor bugs fixed
# Changelog
## 0.142.0
- This release allows the use of videos in preview frames, so you can show off your models in a more dynamic fashion, and also adds indexer support for the upcoming DragonFruit resin slicer VOXL file format.
- There are also a number of fixes to metadata scanning and other background jobs, as well as a large behind-the-scenes refactor of presupported relationships which will lead to some new features in the next release.
- Details: <https://github.com/manyfold3d/manyfold/releases/tag/v0.142.0>
## 0.140.1 (18-05-2026)
- Minor bugs fixed
## 0.140.1
- Bump version to 0.140.1
- Detailed changes https://github.com/manyfold3d/manyfold/compare/v0.139.3...v0.140.1

View File

@@ -1,7 +1,7 @@
name: "Manyfold"
slug: manyfold
description: "Manyfold 3D model manager as a Home Assistant add-on, using the upstream image with configurable library/index paths."
version: "0.140.1"
version: "0.142.0"
url: "https://github.com/alexbelgium/hassio-addons/tree/master/manyfold"
image: ghcr.io/alexbelgium/manyfold-{arch}
arch:

View File

@@ -1,4 +1,8 @@
## 33.0.3-2 (2026-05-29)
- Fix: Change default data directory for new installations from /config/data to /share/nextcloud
- Add data_location option to allow users to customize the Nextcloud data directory
## 33.0.3 (2026-05-02)
- Update to latest version from linuxserver/docker-nextcloud (changelog : https://github.com/linuxserver/docker-nextcloud/releases)

View File

@@ -142,6 +142,7 @@ schema:
keyfile: str
localdisks: str?
networkdisks: str?
data_location: str?
skip_permissions_check: bool?
trusted_domains: str?
use_own_certs: bool
@@ -151,5 +152,5 @@ slug: nextcloud_ocr
uart: true
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/nextcloud
version: "33.0.3"
version: "33.0.3-2"
webui: https://[HOST]:[PORT:443]

View File

@@ -16,17 +16,31 @@ mkdir -p /data/config
chmod 755 -R /data/config
chown -R "$PUID:$PGID" "/data/config"
# Check data_location option
if bashio::config.has_value "data_location"; then
custom_data_location="$(bashio::config 'data_location')"
# Validate path is in an allowed location
location_ok=""
for location in "/share" "/config" "/data" "/mnt"; do
if [[ "$custom_data_location" == "$location"* ]]; then
location_ok=true
fi
done
if [ -z "$location_ok" ]; then
bashio::log.warning "Your data_location value can only be set in /share, /config, /data or /mnt. Falling back to default."
custom_data_location=""
fi
fi
# Check current version
if [ -f /data/config/www/nextcloud/config/config.php ]; then
datadirectory="$(sed -n "s|.*datadirectory.*' => '*\(.*[^ ]\) *',.*|\1|p" /data/config/www/nextcloud/config/config.php)"
echo "... data directory detected : $datadirectory"
else
datadirectory=/config/data
datadirectory="${custom_data_location:-/share/nextcloud}"
echo "Nextcloud is not installed yet, the default data directory is : $datadirectory. You can change it during nextcloud installation."
mkdir -p /config/data
chmod 755 /config/data
mkdir -p /share/nextcloud
chmod 755 /share/nextcloud
mkdir -p "$datadirectory"
chmod 755 "$datadirectory"
fi
# Is the directory valid