fix: auto update system adjustments

This commit is contained in:
Bastien Wirtz
2026-01-18 14:38:43 +01:00
parent 48fd2f5475
commit dd2ccce8dc
5 changed files with 47 additions and 59 deletions

View File

@@ -125,6 +125,9 @@ links:
icon: "fas fa-file-alt"
url: "#page2"
# Optional: enable periodic refresh for all smart cards that implements it (unless overriden at service configuration level).
updateIntervalMs: 30000 # interval in milliseconds, minimum is 1000 (1s). Remove or set to 0 to disable. Can be overriden at service level. (default disabled)
# Services
# First level array represents a group.
# Leave only a "items" key if not using group (group name, icon & tagstyle are optional, section separation will not be displayed).
@@ -183,9 +186,9 @@ Empty values (either in `config.yml` or the endpoint data) will hide the element
## Connectivity checks
As a webapp (PWA) the dashboard can still be displayed when your homer server is offline.
The connectivity checker periodically sends a HEAD request bypassing the PWA cache to the dashbord page to make sure it's still reachable.
The connectivity checker periodically sends a HEAD request bypassing the PWA cache to the dashboard page to make sure it's still reachable.
It can be useful when you access your dashboard through a VPN or ssh tunnel for example, to know if your conection is up. It also helps when using an authentication proxy, it will reload the page if the authentication expires (when a redirect is send in response to the HEAD request).
It can be useful when you access your dashboard through a VPN or ssh tunnel for example, to know if your connection is up. It also helps when using an authentication proxy, it will reload the page if the authentication expires (when a redirect is send in response to the HEAD request).
## Style Options

View File

@@ -1,6 +1,6 @@
# Smart cards
Smart cards provide specific integrations for external services. They display additional information and extra features beyond basic service card. Smart cards are enabled by adding a `type` key to the service item in your YAML configuration.
Smart cards provide specific integration for external services. They display additional information and extra features beyond basic service card. Smart cards are enabled by adding a `type` key to the service item in your YAML configuration.
Each service integration has different requirements and may need additional configuration parameters (see card list below).
@@ -8,7 +8,7 @@ Each service integration has different requirements and may need additional conf
> Your `config.yml` file is exposed at `/assets/config.yml` via HTTP. Any sensitive information (like API keys)
> in this file is visible to anyone who can access your Homer instance. Only include API keys if your Homer
> instance is protected by authentication or access controls **or use a proxy like [`CORSair`](https://github.com/bastienwirtz/corsair)
> to inject your credentials safely**, using environment variable on the server side.
> to inject your credentials safely**, using environment variable on the server side.
Available services are located in `src/components/`:
@@ -40,7 +40,7 @@ Available services are located in `src/components/`:
- [Olivetin](#olivetin)
- [OpenHAB](#openhab)
- [OpenWeatherMap](#openweathermap)
- [Paperless-NGX](#paperlessng)
- [Paperless-NGX](#paperless-ngx)
- [PeaNUT](#peanut)
- [PiAlert](#pialert)
- [PiHole](#pihole)
@@ -69,7 +69,7 @@ Available services are located in `src/components/`:
>
> - All services hosted on the **same domain** as Homer (mydomain.tld/pihole, mydomain.tld/proxmox) to avoid cross-domain request entirely.
> - All services configured to **accept cross-site requests** by sending the necessary CORS headers (either directly in service configuration or via proxy).
> - **Use a proxy** to add the necessary CORS headers (lot of options, some of them described [here](https://enable-cors.org/server.html). Also check [`CORSair`](https://github.com/bastienwirtz/corsair), a light and simple solution)
> - **Use a proxy** to add the necessary CORS headers (lot of options, some of them described [here](https://enable-cors.org/server.html). Also check [`CORSair`](https://github.com/bastienwirtz/corsair), a light and simple solution).
>
> If you experience any issues, see the [troubleshooting](troubleshooting.md#my-service-card-doesnt-work-nothing-appears-or-offline-status-is-displayed-pi-hole-sonarr-ping-) page.
@@ -83,7 +83,6 @@ Available services are located in `src/components/`:
endpoint: https://my-service-api.url # Optional: alternative base URL used to fetch service data when necessary.
useCredentials: false # Optional: Override global proxy.useCredentials configuration.
headers: # Optional: Override global proxy.headers configuration.
autoUpdateInterval: # Optional: Time in ms. Some services can periodically fetch data (see below)
```
If a subtitle is provided, (using the `subtitle` configuration key), **it will override (hide)** any custom information displayed on the subtitle line by the custom integration.
@@ -163,7 +162,6 @@ Displays unread article count and total subscriptions from your FreshRSS server.
- name: "FreshRSS"
type: "FreshRSS"
url: https://my-service.url
autoUpdateInterval: 5000 # (Optional) Interval (in ms) for updating the stats
username: "<---your-username--->"
password: "<---your-password--->"
```
@@ -180,16 +178,13 @@ Two lines are needed in the config.yml :
```
Optionally, the results can be filtered to only include jobs in the defined groups:
```yaml
groups: [Services, External]
```
The status can be checked regularly by defining an update Interval in ms:
```yaml
autoUpdateInterval: 5000
```
The average times can be hidden (saves their calculation also) by setting the following:
```yaml
hideaverages: true
```
@@ -313,7 +308,7 @@ Displays user count, photo/video counts, and storage usage from your Immich serv
## Jellystat
Display the number of concurrent streams on your jellyfin server.
Display the number of concurrent streams on your Jellyfin server.
```yaml
- name: "Jellystat"
@@ -323,7 +318,7 @@ Display the number of concurrent streams on your jellyfin server.
apikey: "<---insert-api-key-here--->"
```
**API Key**: You can create an API key in the dashboard of you jellystat server: settings/API Keys -> Add Key
**API Key**: You can create an API key in the dashboard of you Jellystat server: settings/API Keys -> Add Key
## Lidarr, Prowlarr, Sonarr, Readarr and Radarr
@@ -336,7 +331,6 @@ Two lines are needed in the `config.yml`:
type: "Lidarr" # "Lidarr" "Prowlarr", "Radarr" or "Sonarr"
logo: "assets/tools/sample.png"
url: https://my-service.url
autoUpdateInterval: 5000 # (Optional) Interval (in ms) for updating the status
apikey: "<---insert-api-key-here--->"
```
@@ -390,7 +384,7 @@ The API page can be found: Click on hamburger menu -> Click on your profile -> C
## Medusa
Displays News (grey), Warning (orange) or Error (red) notifications bubbles from the Medusa application.
Displays News (gray), Warning (orange) or Error (red) notifications bubbles from the Medusa application.
```yaml
- name: "Medusa"
@@ -415,7 +409,6 @@ Displays the number of unread articles from your Miniflux RSS reader.
url: https://my-service.url
apikey: "<---insert-api-key-here--->"
style: "status" # Either "status" or "counter"
checkInterval: 60000 # Optional: Interval (in ms) for updating the unread count
```
**API Key**: Generate an API key in Miniflux web interface under **Settings > API Keys > Create a new API key**
@@ -453,7 +446,7 @@ mode](https://docs.nextcloud.com/server/stable/admin_manual/maintenance/upgrade.
## OctoPrint/Moonraker
The OctoPrint/Moonraker service only needs an `apikey` & `endpoint` and optionally a `display` or `url` option. `url` can be used when you click on the service it will launch the `url`
Moonraker's API mimmicks a few of OctoPrint's endpoints which makes these services compatible. See <https://moonraker.readthedocs.io/en/latest/web_api/#octoprint-api-emulation> for details.
Moonraker's API mimics a few of OctoPrint's endpoints which makes these services compatible. See <https://moonraker.readthedocs.io/en/latest/web_api/#octoprint-api-emulation> for details.
```yaml
- name: "Octoprint"
@@ -552,7 +545,6 @@ Displays stats from your PiAlert server.
type: "PiAlert"
logo: "assets/tools/sample.png"
url: https://my-service.url
autoUpdateInterval: 5000 # (Optional) Interval (in ms) for updating the stats
```
## PiHole
@@ -567,7 +559,6 @@ Displays info about your local PiHole instance right on your Homer dashboard.
# endpoint: "https://my-service-api.url" # optional, For v6 API, this is the base URL used to fetch Pi-hole data overwriting the url
apikey: "<---insert-api-key-here--->" # optional, needed if web interface is password protected
apiVersion: 5 # optional, defaults to 5. Use 6 if your PiHole instance uses API v6
autoUpdateInterval: 3000 # optional, defaults to 300000. interval in ms to check Pi-hole status
```
**API Key**: Required only if Pi-hole web interface is password protected. Go to **Settings > API/Web Interface > Show API token**
@@ -592,8 +583,11 @@ Optionally, use `successCodes` to define which HTTP response status codes should
# successCodes: [200, 418] # Optional, default to all 2xx HTTP response status codes
# timeout: 500 # Timeout in ms before ping is aborted. Default 2000
# subtitle: "Bookmark example" # By default, request round trip time is displayed when subtitle is not set
<<<<<<< HEAD
# updateInterval: 5000 # (Optional) Interval (in ms) for updating ping status
# endpoint: "https://www.wikimediastatus.net" # Optional, will override url for pinging
=======
>>>>>>> c25ffaf (fix: auto update system adjustments)
```
## Plex
@@ -683,7 +677,6 @@ for setting up qBittorrent.
type: "qBittorrent"
logo: "assets/tools/sample.png"
url: https://my-service.url # Your rTorrent web UI, f.e. ruTorrent or Flood.
autoUpdateInterval: 2000 # Interval for updating the download, upload rates & torrent count
```
## rTorrent
@@ -700,7 +693,6 @@ for setting up rTorrent.
logo: "assets/tools/sample.png"
url: "https://my-service.url" # Your rTorrent web UI, f.e. ruTorrent or Flood.
xmlrpc: "https://my-service.url:port" # Reverse proxy for rTorrent's XML-RPC.
autoUpdateInterval: 5000 # Interval for updating the download, upload rates & torrent count.
username: "username" # Username for logging into rTorrent (if applicable).
password: "password" # Password for logging into rTorrent (if applicable).
```
@@ -715,7 +707,6 @@ Displays the number of currently active downloads on your SABnzbd instance.
logo: "assets/tools/sample.png"
url: https://my-service.url
apikey: "<---insert-api-key-here--->"
autoUpdateInterval: 5000 # (Optional) Interval (in ms) for updating the download count
```
**API Key**: An API key is required, and can be obtained from the "Config" > "General" section of the SABnzbd config in the web UI.
@@ -729,7 +720,6 @@ Displays info about the total number of disk passed and failed S.M.A.R.T and scr
type: "Scrutiny"
logo: "assets/tools/sample.png"
url: https://my-service.url
autoUpdateInterval: 5000 # (Optional) Interval (in ms) for updating the status
```
## SpeedtestTracker
@@ -752,7 +742,6 @@ Displays the number of currently active streams on you Plex instance.
type: "Tautulli"
logo: "assets/tools/sample.png"
url: https://my-service.url
autoUpdateInterval: 5000 # (Optional) Interval (in ms) for updating the status
apikey: "<---insert-api-key-here--->"
```
@@ -780,7 +769,6 @@ Displays the number of currently queued items for transcoding on your Tdarr inst
type: "Tdarr"
logo: "assets/tools/sample.png"
url: https://my-service.url
autoUpdateInterval: 5000 # (Optional) Interval (in ms) for updating the queue & error counts
```
## Traefik
@@ -808,7 +796,6 @@ The service communicates with the Transmission RPC interface which needs to be a
url: "http://192.168.1.2:9091" # Your Transmission web interface URL
type: "Transmission"
auth: "username:password" # Optional: HTTP Basic Auth
autoUpdateInterval: 5000 # Optional: Interval for refreshing data (ms)
target: "_blank" # Optional: HTML a tag target attribute
```

View File

@@ -67,6 +67,10 @@ links:
# icon: "fas fa-file-alt"
# url: "#additional-page"
# Optional: enable periodic refresh for all smart cards that implements it (unless overriden at service configuration level).
updateIntervalMs: 30000 # interval in milliseconds, minimum is 1000 (1s). Remove or set to 0 to disable. Can be overriden at service level. (default disabled)
# Services
# First level array represent a group.
# Leave only a "items" key if not using group (group name, icon & tagstyle are optional, section separation will not be displayed).

View File

@@ -23,7 +23,8 @@ export default {
if (this.endpoint && this.endpoint.endsWith("/")) {
this.endpoint = this.endpoint.slice(0, -1);
}
},
beforeMount: function () {
// Initialize auto-update if configured
this.initAutoUpdate();
},
@@ -95,21 +96,21 @@ export default {
},
getUpdateInterval: function () {
// Check if auto-update is explicitly disabled for this service
if (this.item.autoUpdateInterval === false) {
if (
this.item.updateInterval === false ||
this.item.updateInterval === 0
) {
return 0;
}
// Use service-specific interval if defined
if (this.item.autoUpdateInterval) {
return parseInt(this.item.autoUpdateInterval, 10) || 0;
if (this.item.updateInterval) {
return parseInt(this.item.updateInterval, 10) || 0;
}
// Check for deprecated keys and warn users
const deprecatedKeys = [
"interval",
"updateInterval",
"checkInterval",
"localCheckInterval",
"downloadInterval",
"rateInterval",
"torrentInterval",
@@ -119,43 +120,25 @@ export default {
if (this.item[key]) {
console.warn(
`[DEPRECATED] Service "${this.item.name || "unknown"}" uses deprecated config key "${key}". ` +
`Please use "autoUpdateInterval" instead. Support for "${key}" will be removed in a future version.`,
`Please use "updateInterval" instead. Support for "${key}" will be removed in a future version.`,
);
return parseInt(this.item[key], 10) || 0;
}
}
// Use global auto-update configuration
return this.getGlobalAutoUpdateInterval();
return this.getGlobalUpdateInterval();
},
getGlobalAutoUpdateInterval: function () {
const globalAutoUpdate = this.globalConfig.autoUpdate;
getGlobalUpdateInterval: function () {
const globalAutoUpdate = this.globalConfig.updateIntervalMs;
// If auto-update is not configured globally, disable
if (!globalAutoUpdate) {
return 0;
}
// If global auto-update is explicitly disabled
if (globalAutoUpdate.enabled === false) {
return 0;
}
// If autoUpdate is just a number (simplified config)
if (typeof globalAutoUpdate === "number") {
return globalAutoUpdate;
}
// If autoUpdate is an object, use defaultInterval
if (
typeof globalAutoUpdate === "object" &&
globalAutoUpdate.defaultInterval
) {
return parseInt(globalAutoUpdate.defaultInterval, 10) || 0;
}
return 0;
return parseInt(globalAutoUpdate, 10) || 0;
},
},
};

View File

@@ -4,6 +4,10 @@
* its own setInterval timer, all components register with this centralized scheduler.
*
*/
const TICK_INTERVAL_MS = 1000; // 1 second tick resolution
const MIN_INTERVAL_MS = TICK_INTERVAL_MS; // Minimum allowed update interval
class UpdateScheduler {
constructor() {
this.registeredComponents = new Map();
@@ -18,6 +22,13 @@ class UpdateScheduler {
return;
}
if (intervalMs < MIN_INTERVAL_MS) {
console.warn(
`UpdateScheduler: Interval ${intervalMs}ms is below minimum. Adjusting to ${MIN_INTERVAL_MS}ms`,
);
intervalMs = MIN_INTERVAL_MS;
}
const intervalSeconds = Math.floor(intervalMs / 1000);
const componentId = this.generateComponentId(component);
@@ -60,7 +71,7 @@ class UpdateScheduler {
this.globalTimer = setInterval(() => {
this.tickCount++;
this.processUpdates();
}, 1000);
}, TICK_INTERVAL_MS);
console.log("UpdateScheduler: Global timer started");
}