Add Glance community homelab widgets
This commit is contained in:
@@ -93,6 +93,165 @@ pages:
|
||||
|
||||
- size: full
|
||||
widgets:
|
||||
- type: group
|
||||
widgets:
|
||||
- type: custom-api
|
||||
title: Immich
|
||||
title-url: https://immich.kaleschke.info
|
||||
cache: 10m
|
||||
url: http://immich_server:2283/api/server/statistics
|
||||
headers:
|
||||
x-api-key: ${GLANCE_IMMICH_API_KEY}
|
||||
subrequests:
|
||||
storage:
|
||||
url: http://immich_server:2283/api/server/storage
|
||||
headers:
|
||||
x-api-key: ${GLANCE_IMMICH_API_KEY}
|
||||
template: |
|
||||
{{ $photos := .JSON.Int "photos" }}
|
||||
{{ $videos := .JSON.Int "videos" }}
|
||||
{{ $usageGiB := div (toFloat (.JSON.Int "usage")) 1073741824.0 }}
|
||||
{{ $storage := .Subrequest "storage" }}
|
||||
{{ $storageOK := and (ge $storage.Response.StatusCode 200) (le $storage.Response.StatusCode 299) }}
|
||||
{{ $percentage := 0.0 }}
|
||||
{{ if $storageOK }}{{ $percentage = $storage.JSON.Float "diskUsagePercentage" }}{{ end }}
|
||||
<div class="flex justify-between text-center">
|
||||
<div>
|
||||
<div class="color-highlight size-h3">{{ $photos | formatNumber }}</div>
|
||||
<div class="size-h6 uppercase">Fotos</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="color-highlight size-h3">{{ $videos | formatNumber }}</div>
|
||||
<div class="size-h6 uppercase">Videos</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="color-highlight size-h3">{{ printf "%.0f" $usageGiB }} GiB</div>
|
||||
<div class="size-h6 uppercase">Medien</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 8px; margin-top: 14px; border-radius: 999px; overflow: hidden; background: color-mix(in srgb, var(--color-text-subdue) 22%, transparent);">
|
||||
<div style="height: 100%; width: {{ if $storageOK }}{{ printf "%.1f" $percentage }}%{{ else }}0%{{ end }}; border-radius: 999px; background: var(--color-primary);"></div>
|
||||
</div>
|
||||
<div class="size-h6 color-subdue" style="margin-top: 8px;">{{ if $storageOK }}{{ printf "%.1f" $percentage }}% Speicher belegt{{ else }}Speicher API nicht verfuegbar{{ end }}</div>
|
||||
|
||||
- type: custom-api
|
||||
title: Paperless
|
||||
title-url: https://paperless.kaleschke.info
|
||||
cache: 5m
|
||||
url: http://paperless-ngx:8000/api/statistics/
|
||||
headers:
|
||||
Authorization: Token ${GLANCE_PAPERLESS_TOKEN}
|
||||
Accept: application/json
|
||||
template: |
|
||||
<div class="flex justify-between text-center">
|
||||
<div>
|
||||
<div class="color-highlight size-h3">{{ .JSON.Int "documents_total" | formatNumber }}</div>
|
||||
<div class="size-h6 uppercase">Dokumente</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="color-highlight size-h3">{{ .JSON.Int "documents_inbox" | formatNumber }}</div>
|
||||
<div class="size-h6 uppercase">Inbox</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="color-highlight size-h3">{{ .JSON.Int "character_count" | formatNumber }}</div>
|
||||
<div class="size-h6 uppercase">Zeichen</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
- type: group
|
||||
widgets:
|
||||
- type: custom-api
|
||||
title: Internet Speed
|
||||
title-url: https://speedtest.kaleschke.info
|
||||
cache: 1h
|
||||
url: http://speedtest-tracker/api/v1/results/latest
|
||||
headers:
|
||||
Authorization: Bearer ${GLANCE_SPEEDTEST_API_TOKEN}
|
||||
Accept: application/json
|
||||
subrequests:
|
||||
stats:
|
||||
url: http://speedtest-tracker/api/v1/stats
|
||||
headers:
|
||||
Authorization: Bearer ${GLANCE_SPEEDTEST_API_TOKEN}
|
||||
Accept: application/json
|
||||
template: |
|
||||
{{ $stats := .Subrequest "stats" }}
|
||||
{{ $downloadChange := percentChange (.JSON.Float "data.download_bits") ($stats.JSON.Float "data.download.avg_bits") }}
|
||||
{{ $uploadChange := percentChange (.JSON.Float "data.upload_bits") ($stats.JSON.Float "data.upload.avg_bits") }}
|
||||
{{ $pingChange := percentChange (.JSON.Float "data.ping") ($stats.JSON.Float "data.ping.avg") }}
|
||||
<div class="flex justify-between text-center">
|
||||
<div>
|
||||
<div class="size-small {{ if gt $downloadChange 0.0 }}color-positive{{ else if lt $downloadChange 0.0 }}color-negative{{ else }}color-primary{{ end }}">{{ $downloadChange | printf "%+.1f%%" }}</div>
|
||||
<div class="color-highlight size-h3">{{ .JSON.Float "data.download_bits" | mul 0.000001 | printf "%.1f" }}</div>
|
||||
<div class="size-h6 uppercase">Download</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="size-small {{ if gt $uploadChange 0.0 }}color-positive{{ else if lt $uploadChange 0.0 }}color-negative{{ else }}color-primary{{ end }}">{{ $uploadChange | printf "%+.1f%%" }}</div>
|
||||
<div class="color-highlight size-h3">{{ .JSON.Float "data.upload_bits" | mul 0.000001 | printf "%.1f" }}</div>
|
||||
<div class="size-h6 uppercase">Upload</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="size-small {{ if lt $pingChange 0.0 }}color-positive{{ else if gt $pingChange 0.0 }}color-negative{{ else }}color-primary{{ end }}">{{ $pingChange | printf "%+.1f%%" }}</div>
|
||||
<div class="color-highlight size-h3">{{ .JSON.Float "data.ping" | printf "%.0f ms" }}</div>
|
||||
<div class="size-h6 uppercase">Ping</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
- type: custom-api
|
||||
title: Drive Health
|
||||
title-url: https://scrutiny.kaleschke.info
|
||||
cache: 1h
|
||||
url: http://scrutiny:8080/api/summary
|
||||
method: GET
|
||||
options:
|
||||
filter_archived: true
|
||||
sort_by: device.device_name
|
||||
sort_order: asc
|
||||
template: |
|
||||
{{- $filterArchived := .Options.filter_archived }}
|
||||
{{- $sortBy := .Options.sort_by }}
|
||||
{{- $sortOrder := .Options.sort_order }}
|
||||
{{- $drives := .JSON.Array "data.summary|@values" }}
|
||||
{{- $sorted := $drives }}
|
||||
{{- if or (eq $sortBy "device.capacity") (eq $sortBy "smart.power_on_hours") }}
|
||||
{{- $sorted = sortByInt $sortBy $sortOrder $drives }}
|
||||
{{- else }}
|
||||
{{- $sorted = sortByString $sortBy $sortOrder $drives }}
|
||||
{{- end }}
|
||||
{{- $total := 0 }}
|
||||
{{- range $sorted }}
|
||||
{{- $archived := .Get "device.archived" }}
|
||||
{{- $archivedBool := false }}
|
||||
{{- if $archived }}{{- $archivedBool = eq $archived.Raw "true" }}{{- end }}
|
||||
{{- if and $filterArchived $archivedBool }}{{- continue }}{{- end }}
|
||||
{{- $total = add $total 1 }}
|
||||
{{- end }}
|
||||
{{- $count := 0 }}
|
||||
{{- range $sorted }}
|
||||
{{- $archived := .Get "device.archived" }}
|
||||
{{- $archivedBool := false }}
|
||||
{{- if $archived }}{{- $archivedBool = eq $archived.Raw "true" }}{{- end }}
|
||||
{{- if and $filterArchived $archivedBool }}{{- continue }}{{- end }}
|
||||
{{- $count = add $count 1 }}
|
||||
{{- $device := .Get "device" }}
|
||||
{{- $deviceName := $device.String "device_name" }}
|
||||
{{- $model := $device.String "model_name" }}
|
||||
{{- $wwn := $device.String "wwn" }}
|
||||
{{- $days := printf "%.0f" (div (.Get "smart.power_on_hours").Num 24) }}
|
||||
{{- $capacity := printf "%.0f" (div (.Get "device.capacity").Num 1000000000000) }}
|
||||
{{- $status := (.Get "device.device_status").Num }}
|
||||
{{- $latestTemp := index (.Array "temp_history") (sub (len (.Array "temp_history")) 1) }}
|
||||
{{- $latestTempValue := $latestTemp.Int "temp" }}
|
||||
<div class="flex justify-between items-center" style="gap: 12px; margin-top: 10px;">
|
||||
<a href="https://scrutiny.kaleschke.info/web/device/{{ $wwn }}" target="_blank">
|
||||
<div class="color-highlight" style="font-weight: 700; text-transform: uppercase;">/DEV/{{ $deviceName }} - {{ $capacity }}TB - {{ $latestTempValue }}C</div>
|
||||
<div class="size-h6 color-subdue">{{ $model }} - {{ $days }} Tage Laufzeit</div>
|
||||
</a>
|
||||
<span class="{{ if eq $status 0.0 }}color-positive{{ else }}color-negative{{ end }}" style="font-size: 20px;">•</span>
|
||||
</div>
|
||||
{{- if lt $count $total }}<hr class="color-secondary" style="margin: 10px 0; border: none; border-bottom: 1px solid currentColor;" />{{- end }}
|
||||
{{- end }}
|
||||
|
||||
- type: monitor
|
||||
title: Core, Security und Ingress
|
||||
cache: 1m
|
||||
|
||||
@@ -5,6 +5,9 @@ services:
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
TZ: Europe/Berlin
|
||||
GLANCE_IMMICH_API_KEY: ${GLANCE_IMMICH_API_KEY:-}
|
||||
GLANCE_PAPERLESS_TOKEN: ${GLANCE_PAPERLESS_TOKEN:-}
|
||||
GLANCE_SPEEDTEST_API_TOKEN: ${GLANCE_SPEEDTEST_API_TOKEN:-}
|
||||
volumes:
|
||||
- ./config:/app/config:ro
|
||||
networks:
|
||||
|
||||
Reference in New Issue
Block a user