diff --git a/homeassistant-addon/CHANGELOG.md b/homeassistant-addon/CHANGELOG.md index e2c7a8f..9150932 100644 --- a/homeassistant-addon/CHANGELOG.md +++ b/homeassistant-addon/CHANGELOG.md @@ -9,6 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 If this add-on saves you time, you can [buy me a coffee](https://buymeacoffee.com/dougrathbone). +## [1.35.0] - 2026-09-29 + +### Fixed + +- **A USB PC Interface stuck while opening is now closed and reopened automatically.** (#122) +- **Startup waits for the C-Bus interface before polling, avoiding repeated command failures.** (#122) +- **Discovery keeps retrying while the C-Bus interface is unavailable.** (#122) +- **Managed C-Gate file logs stay bounded between add-on restarts.** Set the maximum C-Gate log size option to change the 500 MiB default. (#122) + +## [1.34.16] - 2026-09-29 + +### Fixed + +- **USB PC Interface recovery and managed C-Gate log limits.** (#122) + ## [1.34.15] - 2026-09-28 ### Fixed diff --git a/homeassistant-addon/DOCS.md b/homeassistant-addon/DOCS.md index cf827e2..4e24373 100644 --- a/homeassistant-addon/DOCS.md +++ b/homeassistant-addon/DOCS.md @@ -58,6 +58,7 @@ These settings only apply when `cgate_mode` is set to `managed`. | `cgate_download_url` | string | (empty) | Override the default download URL for C-Gate. Leave empty to use the official Clipsal URL. | | `cgate_download_sha256` | string | (empty) | Optional SHA256 of the C-Gate zip. When set, download and upload installs fail on mismatch. Downloads from the built-in default URL are verified against a checksum pinned in the install script; setting this overrides that pin (the escape hatch if Clipsal re-releases the zip). Required for a custom `cgate_download_url`; uploads without it proceed with a log warning and no integrity check. | | `cgate_force_reinstall` | boolean | `false` | Reinstall/upgrade C-Gate from the install source on the next start. Once C-Gate is installed it is normally kept as is across restarts; turn this on to replace it (for example to move to a newer C-Gate version). Your project DBs and config are preserved. Turn it back off after the upgrade, or C-Gate reinstalls on every boot. | +| `cgate_log_max_mb` | integer | `500` | Maximum total size in MiB for managed C-Gate file logs. The add-on checks every 15 minutes and removes the oldest closed log files first. | | `cgate_serial_device` | device | (empty) | **BETA — opt-in, field-tested with 5500PC and 5500PCU.** Dropdown of the serial devices detected on the HA host. Prefer a `/dev/serial/by-id/...` alias over a bare `/dev/ttyUSB0`: it survives replugging into another USB port. Hidden optional field; leave empty to disable. See "USB-serial PCI support" below. | | `cgate_external_clients` | list of objects | `[]` | Addresses allowed to connect to the managed C-Gate (for tools such as C-Bus Toolkit), each with an `address` and a `level` of `monitor`, `operate` or `program`. Empty means the add-on itself only. **C-Gate has no authentication on its ports** — see "Letting external clients reach managed C-Gate" below before using this. | @@ -98,6 +99,16 @@ On every start the add-on: - if log files still exceed 500 MiB total, deletes the oldest segments until under that cap +While the add-on remains running, it repeats the size and age cleanup every +15 minutes. Set the optional `cgate_log_max_mb` value (50–10000, default 500) +to choose the maximum retained C-Gate file-log size. Files C-Gate is actively +writing are never deleted; its native rotation closes them before cleanup. + +This is separate from the add-on log shown by Home Assistant. cgateweb writes +that log to stdout/stderr so Supervisor manages it. `/data` is already the +standard persistent add-on volume, so mapping another host folder does not +provide Home Assistant log rotation and is not required. + Your project databases and `config/` are never touched. The active `event.log` is kept; only older rotated segments are eligible for pruning. diff --git a/homeassistant-addon/config.yaml b/homeassistant-addon/config.yaml index 796b611..43cc937 100644 --- a/homeassistant-addon/config.yaml +++ b/homeassistant-addon/config.yaml @@ -1,5 +1,5 @@ name: "C-Gate Web Bridge" -version: "1.34.15" +version: "1.35.0" slug: cgateweb description: "Bridge between Clipsal C-Bus systems and MQTT/Home Assistant" url: "https://github.com/dougrathbone/cgateweb" @@ -132,6 +132,7 @@ schema: # ── C-Gate Managed Mode ── cgate_install_source: "list(download|upload)?" cgate_download_url: "str?" + cgate_log_max_mb: "int(50,10000)?" cgate_download_sha256: "str?" cgate_force_reinstall: "bool?" # USB-serial PCI passthrough (beta, issue #28): opt-in. The device schema diff --git a/homeassistant-addon/rootfs/etc/cont-init.d/cgate-install.sh b/homeassistant-addon/rootfs/etc/cont-init.d/cgate-install.sh index a20278b..5b995e5 100755 --- a/homeassistant-addon/rootfs/etc/cont-init.d/cgate-install.sh +++ b/homeassistant-addon/rootfs/etc/cont-init.d/cgate-install.sh @@ -33,11 +33,13 @@ CGATEWEB_DEFAULT_PAYLOAD_SHA256="b135a367f435b63ec0a08e5cde0b96735da23c8a48f3f48 # Managed C-Gate log retention (#81). C-Gate writes unbounded files under # /data/cgate/logs/ and rotated event-file segments; without a cap a busy -# network can fill the host SD card. Pruned on every boot before C-Gate starts. +# network can fill the host SD card. Pruned on every boot before C-Gate starts +# and periodically by the cgate-log-pruner service while it remains running. CGATEWEB_LOG_MAX_BYTES="${CGATEWEB_LOG_MAX_BYTES:-524288000}" # 500 MiB CGATEWEB_LOG_MAX_AGE_DAYS="${CGATEWEB_LOG_MAX_AGE_DAYS:-7}" CGATEWEB_EVENT_FILE_SPLIT_SIZE="${CGATEWEB_EVENT_FILE_SPLIT_SIZE:-5000000}" # 5 MiB (C-Gate default) CGATEWEB_EVENT_FILE_SPLIT_COUNT="${CGATEWEB_EVENT_FILE_SPLIT_COUNT:-50}" # ~250 MiB of event segments +CGATEWEB_PROC_ROOT="${CGATEWEB_PROC_ROOT:-/proc}" # The identity-aware serial resolver (issue #28) and the file it publishes its # answer to. Both are overridable so the unit tests can run the repo copy of @@ -370,10 +372,23 @@ _cgateweb_stat_mtime() { stat -c '%Y' "$1" 2>/dev/null || stat -f '%m' "$1" 2>/dev/null || echo 0 } -# Return 0 when a file under the managed C-Gate install may be pruned. -# Only log directories and rotated event-file segments are eligible — never -# Projects/, config/, or the live event.log C-Gate is writing. -_cgateweb_prune_cgate_logs_is_prunable() { +# Return 0 when a running process currently has the file open. Runtime pruning +# must not unlink an active C-Gate log: the JVM would keep writing to the +# unlinked inode, so the disk space would remain consumed but become invisible +# to later retention passes. Startup pruning normally finds no open files. +_cgateweb_log_file_is_open() { + local file="$1" fd target + for fd in "${CGATEWEB_PROC_ROOT}"/[0-9]*/fd/*; do + [[ -e "${fd}" || -L "${fd}" ]] || continue + target=$(readlink -f "${fd}" 2>/dev/null || true) + [[ "${target}" == "${file}" ]] && return 0 + done + return 1 +} + +# Return 0 for files that count toward managed C-Gate's log budget. Only log +# directories and event-file segments are in scope — never Projects/ or config/. +_cgateweb_prune_cgate_logs_is_in_scope() { local cgate_dir="$1" file="$2" case "${file}" in "${cgate_dir}/logs"/*|"${cgate_dir}/log"/*) return 0 ;; @@ -387,9 +402,18 @@ _cgateweb_prune_cgate_logs_is_prunable() { esac } +# Return 0 when an in-scope file can safely be deleted. An open file still +# counts toward the cap, but remains until C-Gate closes or rotates it. +_cgateweb_prune_cgate_logs_is_prunable() { + local cgate_dir="$1" file="$2" + _cgateweb_prune_cgate_logs_is_in_scope "${cgate_dir}" "${file}" || return 1 + _cgateweb_log_file_is_open "${file}" && return 1 + return 0 +} + # Prune C-Gate log files under the managed install directory. Runs on every -# boot before C-Gate starts so a reinstall is not the only way to reclaim -# space (#81). Echoes a one-line summary when anything was removed. +# boot and periodically while C-Gate is running so a long-lived add-on cannot +# grow unchecked (#81). Echoes a one-line summary when anything was removed. _cgateweb_prune_cgate_logs() { local cgate_dir="$1" local max_bytes="${2:-${CGATEWEB_LOG_MAX_BYTES}}" @@ -400,7 +424,7 @@ _cgateweb_prune_cgate_logs() { [[ -d "${cgate_dir}" ]] || return 0 while IFS= read -r -d '' file; do - _cgateweb_prune_cgate_logs_is_prunable "${cgate_dir}" "${file}" || continue + _cgateweb_prune_cgate_logs_is_in_scope "${cgate_dir}" "${file}" || continue candidates+=("${file}") done < <(find "${cgate_dir}" \( -path "${cgate_dir}/logs/*" -o -path "${cgate_dir}/log/*" \ -o -name 'event.*.log' -o -name 'event-*' \) -type f -print0 2>/dev/null) @@ -411,6 +435,7 @@ _cgateweb_prune_cgate_logs() { for file in "${candidates[@]}"; do [[ -f "${file}" ]] || continue + _cgateweb_prune_cgate_logs_is_prunable "${cgate_dir}" "${file}" || continue if find "${file}" -mtime +"${max_age_days}" -print -quit 2>/dev/null | grep -q .; then age_bytes=$(_cgateweb_stat_size "${file}") rm -f "${file}" && deleted_age=$((deleted_age + 1)) && reclaimed=$((reclaimed + age_bytes)) @@ -420,7 +445,7 @@ _cgateweb_prune_cgate_logs() { # Rebuild the candidate list after age pruning. candidates=() while IFS= read -r -d '' file; do - _cgateweb_prune_cgate_logs_is_prunable "${cgate_dir}" "${file}" || continue + _cgateweb_prune_cgate_logs_is_in_scope "${cgate_dir}" "${file}" || continue candidates+=("${file}") done < <(find "${cgate_dir}" \( -path "${cgate_dir}/logs/*" -o -path "${cgate_dir}/log/*" \ -o -name 'event.*.log' -o -name 'event-*' \) -type f -print0 2>/dev/null) @@ -446,6 +471,7 @@ _cgateweb_prune_cgate_logs() { for i in "${!candidates[@]}"; do file="${candidates[$i]}" [[ -f "${file}" ]] || continue + _cgateweb_prune_cgate_logs_is_prunable "${cgate_dir}" "${file}" || continue mtime=$(_cgateweb_stat_mtime "${file}") if [[ ${mtime} -lt ${oldest_mtime} ]]; then oldest_mtime=${mtime} @@ -1128,6 +1154,21 @@ if [[ "${CGATE_MODE}" != "managed" ]]; then exit 0 fi +# Keep the existing 500 MiB default but let managed-mode users choose a lower +# or higher ceiling. The Supervisor schema validates this as an integer; the +# fallback also keeps direct/test execution safe. +CGATE_LOG_MAX_MB=$(bashio::config 'cgate_log_max_mb' '500') +[[ "${CGATE_LOG_MAX_MB}" =~ ^[0-9]+$ ]] || CGATE_LOG_MAX_MB=500 +CGATEWEB_LOG_MAX_BYTES=$((CGATE_LOG_MAX_MB * 1048576)) + +# Reserve at most half of the overall budget for C-Gate's native event-file +# rotation. At the default this preserves the historical 50 x 5 MiB setting; +# smaller user caps reduce the native segment count so the periodic pruner does +# not spend its time fighting a larger built-in retention target. +CGATEWEB_EVENT_FILE_SPLIT_COUNT=$((CGATEWEB_LOG_MAX_BYTES / CGATEWEB_EVENT_FILE_SPLIT_SIZE / 2)) +[[ ${CGATEWEB_EVENT_FILE_SPLIT_COUNT} -lt 2 ]] && CGATEWEB_EVENT_FILE_SPLIT_COUNT=2 +[[ ${CGATEWEB_EVENT_FILE_SPLIT_COUNT} -gt 50 ]] && CGATEWEB_EVENT_FILE_SPLIT_COUNT=50 + # Overridable so tests can point the whole install flow at a temp dir instead # of the real /data/cgate, the same test-seam pattern used by # CGATEWEB_SERIAL_DEVICE_FILE above. Unset in production, so this always diff --git a/homeassistant-addon/rootfs/etc/services.d/cgate-log-pruner/run b/homeassistant-addon/rootfs/etc/services.d/cgate-log-pruner/run new file mode 100755 index 0000000..5971bbe --- /dev/null +++ b/homeassistant-addon/rootfs/etc/services.d/cgate-log-pruner/run @@ -0,0 +1,24 @@ +#!/usr/bin/with-contenv bashio +# Keep managed C-Gate's private file logs bounded between add-on restarts. +set -euo pipefail + +CGATE_MODE=$(bashio::config 'cgate_mode' 'remote') +if [[ "${CGATE_MODE}" != "managed" ]]; then + exec sleep infinity +fi + +CGATE_DIR="${CGATE_DIR:-/data/cgate}" +CGATEWEB_LOG_PRUNE_INTERVAL_SECONDS="${CGATEWEB_LOG_PRUNE_INTERVAL_SECONDS:-900}" +CGATE_LOG_MAX_MB=$(bashio::config 'cgate_log_max_mb' '500') +[[ "${CGATE_LOG_MAX_MB}" =~ ^[0-9]+$ ]] || CGATE_LOG_MAX_MB=500 +CGATEWEB_LOG_MAX_BYTES=$((CGATE_LOG_MAX_MB * 1048576)) + +# Source the install script in library mode so startup and runtime retention +# use exactly the same path allowlist and deletion rules. +export CGATEWEB_INSTALL_SOURCE_ONLY=1 +# shellcheck disable=SC1090 +source "${CGATEWEB_INSTALL_SCRIPT:-/etc/cont-init.d/cgate-install.sh}" + +while sleep "${CGATEWEB_LOG_PRUNE_INTERVAL_SECONDS}"; do + _cgateweb_prune_cgate_logs "${CGATE_DIR}" "${CGATEWEB_LOG_MAX_BYTES}" +done diff --git a/homeassistant-addon/translations/catalog.yaml b/homeassistant-addon/translations/catalog.yaml index e175efe..c9f3728 100644 --- a/homeassistant-addon/translations/catalog.yaml +++ b/homeassistant-addon/translations/catalog.yaml @@ -892,6 +892,85 @@ configuration: (бази даних проєкту та конфігурація зберігаються); у режимі завантаження можна натомість покласти новіший zip у /share/cgate. Вимкніть його після оновлення. + cgate_log_max_mb: + name: + en: Maximum C-Gate Log Size + de: Maximale C-Gate-Protokollgröße + es: Tamaño máximo del registro de C-Gate + fr: Taille maximale des journaux C-Gate + it: Dimensione massima dei log C-Gate + nl: Maximale grootte van C-Gate-logboeken + pt: Tamanho máximo dos registos do C-Gate + ru: Максимальный размер журналов C-Gate + zh: C-Gate 日志最大大小 + ja: C-Gate ログの最大サイズ + ko: 최대 C-Gate 로그 크기 + pl: Maksymalny rozmiar dzienników C-Gate + sv: Maximal storlek för C-Gate-loggar + no: Maksimal størrelse på C-Gate-logger + da: Maksimal størrelse på C-Gate-logfiler + cs: Maximální velikost protokolů C-Gate + uk: Максимальний розмір журналів C-Gate + description: + en: >- + Maximum total size in MiB for managed C-Gate file logs. The oldest + closed log files are removed every 15 minutes. Default: 500. + de: >- + Maximale Gesamtgröße in MiB für Protokolldateien des verwalteten C-Gate. + Die ältesten geschlossenen Dateien werden alle 15 Minuten entfernt. + Standard: 500. + es: >- + Tamaño total máximo en MiB de los archivos de registro de C-Gate + gestionado. Los archivos cerrados más antiguos se eliminan cada 15 + minutos. Predeterminado: 500. + fr: >- + Taille totale maximale en Mio des fichiers journaux du C-Gate géré. Les + plus anciens fichiers fermés sont supprimés toutes les 15 minutes. Par + défaut : 500. + it: >- + Dimensione totale massima in MiB dei file di log di C-Gate gestito. I + file chiusi meno recenti vengono rimossi ogni 15 minuti. Predefinito: + 500. + nl: >- + Maximale totale grootte in MiB voor logbestanden van beheerde C-Gate. De + oudste gesloten bestanden worden elke 15 minuten verwijderd. Standaard: + 500. + pt: >- + Tamanho total máximo em MiB dos ficheiros de registo do C-Gate gerido. + Os ficheiros fechados mais antigos são removidos a cada 15 minutos. + Predefinição: 500. + ru: >- + Максимальный общий размер файлов журналов управляемого C-Gate в МиБ. + Самые старые закрытые файлы удаляются каждые 15 минут. По умолчанию: + 500. + zh: >- + 托管 C-Gate 文件日志的最大总大小(MiB)。每 15 分钟删除最旧的已关闭日志文件。默认值:500。 + ja: >- + マネージド C-Gate のログファイルの合計上限(MiB)です。閉じられた古いログファイルを 15 + 分ごとに削除します。既定値:500。 + ko: >- + 관리형 C-Gate 파일 로그의 최대 총크기(MiB)입니다. 닫힌 로그 파일 중 가장 오래된 파일을 15분마다 + 삭제합니다. 기본값: 500. + pl: >- + Maksymalny łączny rozmiar plików dziennika zarządzanego C-Gate w MiB. + Najstarsze zamknięte pliki są usuwane co 15 minut. Domyślnie: 500. + sv: >- + Maximal total storlek i MiB för hanterade C-Gate-loggfiler. De äldsta + stängda filerna tas bort var 15:e minut. Standard: 500. + no: >- + Maksimal samlet størrelse i MiB for administrerte C-Gate-loggfiler. De + eldste lukkede filene fjernes hvert 15. minutt. Standard: 500. + da: >- + Maksimal samlet størrelse i MiB for administrerede C-Gate-logfiler. De + ældste lukkede filer fjernes hvert 15. minut. Standard: 500. + cs: >- + Maximální celková velikost souborů protokolu spravovaného C-Gate v MiB. + Nejstarší zavřené soubory se odstraňují každých 15 minut. Výchozí + hodnota: 500. + uk: >- + Максимальний загальний розмір файлів журналів керованого C-Gate у МіБ. + Найстаріші закриті файли видаляються кожні 15 хвилин. Типове значення: + 500. cgate_serial_device: name: en: Serial PCI Device (Beta) diff --git a/homeassistant-addon/translations/cs.yaml b/homeassistant-addon/translations/cs.yaml index bd4613c..3ff4b16 100644 --- a/homeassistant-addon/translations/cs.yaml +++ b/homeassistant-addon/translations/cs.yaml @@ -61,6 +61,12 @@ configuration: přeinstalovat/aktualizovat C-Gate ze zdroje instalace (databáze projektu a konfigurace zůstanou zachovány); v režimu nahrávání můžete místo toho umístit novější zip do /share/cgate. Po aktualizaci ji opět vypněte. + cgate_log_max_mb: + name: Maximální velikost protokolů C-Gate + description: >- + Maximální celková velikost souborů protokolu spravovaného C-Gate v MiB. + Nejstarší zavřené soubory se odstraňují každých 15 minut. Výchozí hodnota: + 500. cgate_serial_device: name: Sériové PCI zařízení (beta) description: >- diff --git a/homeassistant-addon/translations/da.yaml b/homeassistant-addon/translations/da.yaml index e1d63e8..6b3600d 100644 --- a/homeassistant-addon/translations/da.yaml +++ b/homeassistant-addon/translations/da.yaml @@ -61,6 +61,11 @@ configuration: (dine projektdatabaser og konfiguration bevares); i upload-tilstand kan du i stedet lægge en nyere zip i /share/cgate. Slå det fra igen efter opgraderingen. + cgate_log_max_mb: + name: Maksimal størrelse på C-Gate-logfiler + description: >- + Maksimal samlet størrelse i MiB for administrerede C-Gate-logfiler. De + ældste lukkede filer fjernes hvert 15. minut. Standard: 500. cgate_serial_device: name: Seriel PCI-enhed (beta) description: >- diff --git a/homeassistant-addon/translations/de.yaml b/homeassistant-addon/translations/de.yaml index 3cc3c55..db41608 100644 --- a/homeassistant-addon/translations/de.yaml +++ b/homeassistant-addon/translations/de.yaml @@ -63,6 +63,12 @@ configuration: Projekt-Datenbanken und Konfiguration bleiben erhalten); im Upload-Modus können Sie stattdessen eine neuere zip in /share/cgate ablegen. Schalten Sie dies nach dem Upgrade wieder aus. + cgate_log_max_mb: + name: Maximale C-Gate-Protokollgröße + description: >- + Maximale Gesamtgröße in MiB für Protokolldateien des verwalteten C-Gate. + Die ältesten geschlossenen Dateien werden alle 15 Minuten entfernt. + Standard: 500. cgate_serial_device: name: Serielles PCI-Gerät (Beta) description: >- diff --git a/homeassistant-addon/translations/en.yaml b/homeassistant-addon/translations/en.yaml index 47b4a6d..447aa7c 100644 --- a/homeassistant-addon/translations/en.yaml +++ b/homeassistant-addon/translations/en.yaml @@ -59,6 +59,11 @@ configuration: the next start (your project DBs and config are preserved). In upload mode you can instead just drop a newer zip into /share/cgate and it upgrades automatically. Turn this back off after the upgrade. + cgate_log_max_mb: + name: Maximum C-Gate Log Size + description: >- + Maximum total size in MiB for managed C-Gate file logs. The oldest closed + log files are removed every 15 minutes. Default: 500. cgate_serial_device: name: Serial PCI Device (Beta) description: >- diff --git a/homeassistant-addon/translations/es.yaml b/homeassistant-addon/translations/es.yaml index b3f76b6..23b1d42 100644 --- a/homeassistant-addon/translations/es.yaml +++ b/homeassistant-addon/translations/es.yaml @@ -63,6 +63,12 @@ configuration: fuente de instalación en el próximo inicio (sus bases de datos de proyecto y la configuración se conservan); en modo de carga puede colocar un zip más reciente en /share/cgate. Desactívelo después de la actualización. + cgate_log_max_mb: + name: Tamaño máximo del registro de C-Gate + description: >- + Tamaño total máximo en MiB de los archivos de registro de C-Gate + gestionado. Los archivos cerrados más antiguos se eliminan cada 15 + minutos. Predeterminado: 500. cgate_serial_device: name: Dispositivo PCI serie (beta) description: >- diff --git a/homeassistant-addon/translations/fr.yaml b/homeassistant-addon/translations/fr.yaml index 7ea4e2f..a8ec919 100644 --- a/homeassistant-addon/translations/fr.yaml +++ b/homeassistant-addon/translations/fr.yaml @@ -67,6 +67,12 @@ configuration: données de projet et la configuration sont conservées) ; en mode upload, vous pouvez aussi déposer un zip plus récent dans /share/cgate. Désactivez-la après la mise à jour. + cgate_log_max_mb: + name: Taille maximale des journaux C-Gate + description: >- + Taille totale maximale en Mio des fichiers journaux du C-Gate géré. Les + plus anciens fichiers fermés sont supprimés toutes les 15 minutes. Par + défaut : 500. cgate_serial_device: name: Périphérique PCI série (bêta) description: >- diff --git a/homeassistant-addon/translations/it.yaml b/homeassistant-addon/translations/it.yaml index 51c87ba..ab4f5dd 100644 --- a/homeassistant-addon/translations/it.yaml +++ b/homeassistant-addon/translations/it.yaml @@ -64,6 +64,11 @@ configuration: avvio (i database del progetto e la configurazione vengono conservati); in modalità upload puoi invece inserire uno zip più recente in /share/cgate. Disattivala dopo l'aggiornamento. + cgate_log_max_mb: + name: Dimensione massima dei log C-Gate + description: >- + Dimensione totale massima in MiB dei file di log di C-Gate gestito. I file + chiusi meno recenti vengono rimossi ogni 15 minuti. Predefinito: 500. cgate_serial_device: name: Dispositivo PCI seriale (beta) description: >- diff --git a/homeassistant-addon/translations/ja.yaml b/homeassistant-addon/translations/ja.yaml index 1f1e40c..c3d6cb3 100644 --- a/homeassistant-addon/translations/ja.yaml +++ b/homeassistant-addon/translations/ja.yaml @@ -47,6 +47,9 @@ configuration: は通常そのまま維持されます。これを有効にすると、次回起動時にインストールソースから C-Gate を再インストール/アップグレードします(プロジェクトのデータベースと設定は保持されます)。アップロードモードでは、代わりに新しい zip を /share/cgate に置くこともできます。アップグレード後はオフに戻してください。 + cgate_log_max_mb: + name: C-Gate ログの最大サイズ + description: マネージド C-Gate のログファイルの合計上限(MiB)です。閉じられた古いログファイルを 15 分ごとに削除します。既定値:500。 cgate_serial_device: name: シリアル PCI デバイス(ベータ) description: >- diff --git a/homeassistant-addon/translations/ko.yaml b/homeassistant-addon/translations/ko.yaml index cd40ff0..c4bc629 100644 --- a/homeassistant-addon/translations/ko.yaml +++ b/homeassistant-addon/translations/ko.yaml @@ -47,6 +47,10 @@ configuration: 관리 모드에서만 사용됩니다. C-Gate는 설치된 후 일반적으로 그대로 유지됩니다. 이 옵션을 켜면 다음 시작 시 설치 소스에서 C-Gate를 다시 설치/업그레이드합니다(프로젝트 데이터베이스와 구성은 유지됩니다). 업로드 모드에서는 대신 최신 zip을 /share/cgate에 넣을 수 있습니다. 업그레이드 후에는 다시 꺼 주세요. + cgate_log_max_mb: + name: 최대 C-Gate 로그 크기 + description: "관리형 C-Gate 파일 로그의 최대 총크기(MiB)입니다. 닫힌 로그 파일 중 가장 오래된 파일을 15분마다 삭제합니다. 기본값: + 500." cgate_serial_device: name: 시리얼 PCI 장치(베타) description: >- diff --git a/homeassistant-addon/translations/nl.yaml b/homeassistant-addon/translations/nl.yaml index 958b83f..a972dc2 100644 --- a/homeassistant-addon/translations/nl.yaml +++ b/homeassistant-addon/translations/nl.yaml @@ -61,6 +61,12 @@ configuration: projectdatabases en configuratie blijven behouden); in upload-modus kunt u in plaats daarvan een nieuwere zip in /share/cgate plaatsen. Schakel dit na de upgrade weer uit. + cgate_log_max_mb: + name: Maximale grootte van C-Gate-logboeken + description: >- + Maximale totale grootte in MiB voor logbestanden van beheerde C-Gate. De + oudste gesloten bestanden worden elke 15 minuten verwijderd. Standaard: + 500. cgate_serial_device: name: Serieel PCI-apparaat (beta) description: >- diff --git a/homeassistant-addon/translations/no.yaml b/homeassistant-addon/translations/no.yaml index 9d566e7..5ff016d 100644 --- a/homeassistant-addon/translations/no.yaml +++ b/homeassistant-addon/translations/no.yaml @@ -61,6 +61,11 @@ configuration: nytt fra installasjonskilden ved neste oppstart (prosjektdatabasene og konfigurasjonen beholdes); i opplastingsmodus kan du i stedet legge en nyere zip i /share/cgate. Slå det av igjen etter oppgraderingen. + cgate_log_max_mb: + name: Maksimal størrelse på C-Gate-logger + description: >- + Maksimal samlet størrelse i MiB for administrerte C-Gate-loggfiler. De + eldste lukkede filene fjernes hvert 15. minutt. Standard: 500. cgate_serial_device: name: Seriell PCI-enhet (beta) description: >- diff --git a/homeassistant-addon/translations/pl.yaml b/homeassistant-addon/translations/pl.yaml index a85152f..1882d90 100644 --- a/homeassistant-addon/translations/pl.yaml +++ b/homeassistant-addon/translations/pl.yaml @@ -61,6 +61,11 @@ configuration: danych projektu i konfiguracja zostają zachowane); w trybie przesyłania możesz zamiast tego umieścić nowszy zip w /share/cgate. Wyłącz ją po aktualizacji. + cgate_log_max_mb: + name: Maksymalny rozmiar dzienników C-Gate + description: >- + Maksymalny łączny rozmiar plików dziennika zarządzanego C-Gate w MiB. + Najstarsze zamknięte pliki są usuwane co 15 minut. Domyślnie: 500. cgate_serial_device: name: Urządzenie PCI szeregowe (beta) description: >- diff --git a/homeassistant-addon/translations/pt.yaml b/homeassistant-addon/translations/pt.yaml index 6179570..3bbd4ce 100644 --- a/homeassistant-addon/translations/pt.yaml +++ b/homeassistant-addon/translations/pt.yaml @@ -62,6 +62,12 @@ configuration: projeto e a configuração são preservadas); no modo de carregamento pode antes colocar um zip mais recente em /share/cgate. Desative isto após a atualização. + cgate_log_max_mb: + name: Tamanho máximo dos registos do C-Gate + description: >- + Tamanho total máximo em MiB dos ficheiros de registo do C-Gate gerido. Os + ficheiros fechados mais antigos são removidos a cada 15 minutos. + Predefinição: 500. cgate_serial_device: name: Dispositivo PCI série (beta) description: >- diff --git a/homeassistant-addon/translations/ru.yaml b/homeassistant-addon/translations/ru.yaml index 7e3b9d6..563d31c 100644 --- a/homeassistant-addon/translations/ru.yaml +++ b/homeassistant-addon/translations/ru.yaml @@ -62,6 +62,11 @@ configuration: запуске (ваши базы данных проекта и конфигурация сохраняются); в режиме загрузки можно вместо этого поместить более новый zip в /share/cgate. Выключите его после обновления. + cgate_log_max_mb: + name: Максимальный размер журналов C-Gate + description: >- + Максимальный общий размер файлов журналов управляемого C-Gate в МиБ. Самые + старые закрытые файлы удаляются каждые 15 минут. По умолчанию: 500. cgate_serial_device: name: Последовательное PCI-устройство (бета) description: >- diff --git a/homeassistant-addon/translations/sv.yaml b/homeassistant-addon/translations/sv.yaml index 8b4d2a8..ae97bcd 100644 --- a/homeassistant-addon/translations/sv.yaml +++ b/homeassistant-addon/translations/sv.yaml @@ -60,6 +60,11 @@ configuration: från installationskällan vid nästa start (dina projektdatabaser och konfiguration bevaras); i uppladdningsläge kan du i stället lägga en nyare zip i /share/cgate. Stäng av detta efter uppgraderingen. + cgate_log_max_mb: + name: Maximal storlek för C-Gate-loggar + description: >- + Maximal total storlek i MiB för hanterade C-Gate-loggfiler. De äldsta + stängda filerna tas bort var 15:e minut. Standard: 500. cgate_serial_device: name: Seriell PCI-enhet (beta) description: >- diff --git a/homeassistant-addon/translations/uk.yaml b/homeassistant-addon/translations/uk.yaml index 4b1f088..672518c 100644 --- a/homeassistant-addon/translations/uk.yaml +++ b/homeassistant-addon/translations/uk.yaml @@ -62,6 +62,12 @@ configuration: (бази даних проєкту та конфігурація зберігаються); у режимі завантаження можна натомість покласти новіший zip у /share/cgate. Вимкніть його після оновлення. + cgate_log_max_mb: + name: Максимальний розмір журналів C-Gate + description: >- + Максимальний загальний розмір файлів журналів керованого C-Gate у МіБ. + Найстаріші закриті файли видаляються кожні 15 хвилин. Типове значення: + 500. cgate_serial_device: name: Послідовний PCI-пристрій (бета) description: >- diff --git a/homeassistant-addon/translations/zh.yaml b/homeassistant-addon/translations/zh.yaml index 35b76c6..6c9724c 100644 --- a/homeassistant-addon/translations/zh.yaml +++ b/homeassistant-addon/translations/zh.yaml @@ -38,6 +38,9 @@ configuration: description: >- 仅在托管模式下使用。C-Gate 安装后通常保持不变。启用此选项可在下次启动时从安装源重新安装/升级 C-Gate(您的项目数据库和配置会被保留);在上传模式下,您也可以将较新的 zip 放入 /share/cgate。升级完成后请将其关闭。 + cgate_log_max_mb: + name: C-Gate 日志最大大小 + description: 托管 C-Gate 文件日志的最大总大小(MiB)。每 15 分钟删除最旧的已关闭日志文件。默认值:500。 cgate_serial_device: name: 串口 PCI 设备(Beta) description: >- diff --git a/package-lock.json b/package-lock.json index 2be651e..f2c8736 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cgateweb", - "version": "1.34.15", + "version": "1.35.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cgateweb", - "version": "1.34.15", + "version": "1.35.0", "license": "MIT", "dependencies": { "adm-zip": "^0.6.1", diff --git a/package.json b/package.json index 296631b..6fadbaa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cgateweb", - "version": "1.34.15", + "version": "1.35.0", "description": "Node.js bridge connecting Clipsal C-Bus automation systems to MQTT for Home Assistant integration", "keywords": [ "cbus", diff --git a/tests/cgateInstallScript.test.js b/tests/cgateInstallScript.test.js index 2d70898..62170d7 100644 --- a/tests/cgateInstallScript.test.js +++ b/tests/cgateInstallScript.test.js @@ -603,6 +603,38 @@ describeBash('cgate-install.sh helpers', () => { expect(r.remaining).toEqual(['event.log']); }); + test('does not unlink a log file that a process has open', () => { + const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'cgate-prune-open-')); + const cgateDir = path.join(dir, 'cgate'); + const procRoot = path.join(dir, 'proc'); + const logFile = path.join(cgateDir, 'logs', 'active.log'); + const closedLogFile = path.join(cgateDir, 'logs', 'closed.log'); + fs.mkdirSync(path.dirname(logFile), { recursive: true }); + fs.mkdirSync(path.join(procRoot, '123', 'fd'), { recursive: true }); + fs.writeFileSync(logFile, 'x'.repeat(5000)); + fs.writeFileSync(closedLogFile, 'x'.repeat(5000)); + fs.symlinkSync(logFile, path.join(procRoot, '123', 'fd', '4')); + + const env = { + ...process.env, + CGATEWEB_INSTALL_SOURCE_ONLY: '1', + CGW_INSTALL_SCRIPT: SCRIPT, + CGATEWEB_SERIAL_DEVICE_LIB: SERIAL_DEVICE_LIB, + CGATEWEB_PROC_ROOT: procRoot, + CGW_ARG_0: cgateDir + }; + const script = ` + set -u + ${BASHIO_STUB_WITH_LOGS} + source "$CGW_INSTALL_SCRIPT" + _cgateweb_prune_cgate_logs "$CGW_ARG_0" 100 0 + `; + execFileSync('bash', ['-c', script], { encoding: 'utf8', env }); + expect(fs.existsSync(logFile)).toBe(true); + expect(fs.existsSync(closedLogFile)).toBe(false); + fs.rmSync(dir, { recursive: true, force: true }); + }); + test('does not touch project databases or config', () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'cgate-prune-safe-')); const cgateDir = path.join(dir, 'cgate'); diff --git a/tests/configSchema.test.js b/tests/configSchema.test.js index 296abb1..d4d5add 100644 --- a/tests/configSchema.test.js +++ b/tests/configSchema.test.js @@ -228,6 +228,7 @@ describe('settings schema — aliases', () => { cover_ramp_duration_sec: 'Seconds; cover_ramp_duration_ms is milliseconds.', cgate_download_sha256: 'Add-on container script only; no runtime setting reads it.', cgate_force_reinstall: 'Add-on container script only; no runtime setting reads it.', + cgate_log_max_mb: 'Add-on container scripts only; no runtime setting reads it.', cgate_external_clients: 'Add-on container script only; no runtime setting reads it.' };