From c260d218350227e59406d224c6e82946b42a4f79 Mon Sep 17 00:00:00 2001 From: damachine Date: Sat, 21 Feb 2026 02:27:20 +0100 Subject: [PATCH 1/3] prepare for version 2.2.6 --- VERSION | 2 +- aur/PKGBUILD | 40 ++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/VERSION b/VERSION index 21bb5e1..bda8fbe 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.5 +2.2.6 diff --git a/aur/PKGBUILD b/aur/PKGBUILD index 061075d..763e5df 100644 --- a/aur/PKGBUILD +++ b/aur/PKGBUILD @@ -20,7 +20,7 @@ source=("git+https://github.com/damachine/coolerdash.git#commit=${_commit}") sha256sums=('SKIP') # SKIP for git repo source builds pkgver() { - cd "${srcdir}/coolerdash" + cd "${srcdir}/${pkgname}" # Fetch latest tags in git repo git fetch --tags git describe --tags --long --match "v*" | sed -E 's/^v//; s/-([0-9]+)-g/\.r\1.g/; s/-/./g' @@ -28,10 +28,10 @@ pkgver() { build() { # Build inside the checked-out repository - cd "${srcdir}/coolerdash" + cd "${srcdir}/${pkgname}" # Remove all previous tarball builds - rm -rf coolerdash-*.pkg.* + rm -rf ${pkgname}-*.pkg.* # Clean any previous builds if a Makefile exists if [[ -f Makefile || -f GNUmakefile ]]; then @@ -44,7 +44,7 @@ build() { check() { # Check in the checked-out repository - cd "${srcdir}/coolerdash" + cd "${srcdir}/${pkgname}" # Verify that the binary was created successfully if [[ -f bin/coolerdash ]]; then @@ -58,27 +58,27 @@ check() { package() { # Binary to /usr/libexec, plugin data stays in /etc/coolercontrol/plugins/ install -dm755 "${pkgdir}/etc/coolercontrol/plugins/coolerdash" - install -Dm755 "${srcdir}/coolerdash/bin/coolerdash" "${pkgdir}/usr/libexec/coolerdash/coolerdash" - install -m644 "${srcdir}/coolerdash/README.md" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/README.md" - install -m644 "${srcdir}/coolerdash/VERSION" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/VERSION" - install -m644 "${srcdir}/coolerdash/CHANGELOG.md" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/CHANGELOG.md" - install -m666 "${srcdir}/coolerdash/etc/coolercontrol/plugins/coolerdash/config.json" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/config.json" + install -Dm755 "${srcdir}/${pkgname}/bin/coolerdash" "${pkgdir}/usr/libexec/coolerdash/coolerdash" + install -m644 "${srcdir}/${pkgname}/README.md" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/README.md" + install -m644 "${srcdir}/${pkgname}/VERSION" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/VERSION" + install -m644 "${srcdir}/${pkgname}/CHANGELOG.md" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/CHANGELOG.md" + install -m666 "${srcdir}/${pkgname}/etc/coolercontrol/plugins/coolerdash/config.json" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/config.json" install -dm755 "${pkgdir}/etc/coolercontrol/plugins/coolerdash/ui" - install -m644 "${srcdir}/coolerdash/etc/coolercontrol/plugins/coolerdash/ui/index.html" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/ui/index.html" - install -m644 "${srcdir}/coolerdash/etc/coolercontrol/plugins/coolerdash/ui/cc-plugin-lib.js" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/ui/cc-plugin-lib.js" - install -m644 "${srcdir}/coolerdash/images/shutdown.png" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/shutdown.png" - install -m644 "${srcdir}/coolerdash/etc/coolercontrol/plugins/coolerdash/manifest.toml" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/manifest.toml" + install -m644 "${srcdir}/${pkgname}/etc/coolercontrol/plugins/coolerdash/ui/index.html" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/ui/index.html" + install -m644 "${srcdir}/${pkgname}/etc/coolercontrol/plugins/coolerdash/ui/cc-plugin-lib.js" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/ui/cc-plugin-lib.js" + install -m644 "${srcdir}/${pkgname}/images/shutdown.png" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/shutdown.png" + install -m644 "${srcdir}/${pkgname}/etc/coolercontrol/plugins/coolerdash/manifest.toml" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/manifest.toml" sed -i "s/{{VERSION}}/${pkgver}/g" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/manifest.toml" sed -i "s/{{VERSION}}/${pkgver}/g" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/ui/index.html" - install -Dm644 "${srcdir}/coolerdash/man/coolerdash.1" "${pkgdir}/usr/share/man/man1/coolerdash.1" - install -Dm644 "${srcdir}/coolerdash/etc/applications/coolerdash.desktop" "${pkgdir}/usr/share/applications/coolerdash.desktop" - install -Dm644 "${srcdir}/coolerdash/etc/udev/rules.d/99-coolerdash.rules" "${pkgdir}/usr/lib/udev/rules.d/99-coolerdash.rules" - install -Dm644 "${srcdir}/coolerdash/etc/icons/coolerdash.svg" "${pkgdir}/usr/share/icons/hicolor/scalable/apps/coolerdash.svg" - install -Dm644 "${srcdir}/coolerdash/etc/systemd/coolerdash-helperd.service" "${pkgdir}/usr/lib/systemd/system/coolerdash-helperd.service" - install -Dm644 "${srcdir}/coolerdash/etc/systemd/cc-plugin-coolerdash.service.d/startup-delay.conf" "${pkgdir}/etc/systemd/system/cc-plugin-coolerdash.service.d/startup-delay.conf" + install -Dm644 "${srcdir}/${pkgname}/man/coolerdash.1" "${pkgdir}/usr/share/man/man1/coolerdash.1" + install -Dm644 "${srcdir}/${pkgname}/etc/applications/coolerdash.desktop" "${pkgdir}/usr/share/applications/coolerdash.desktop" + install -Dm644 "${srcdir}/${pkgname}/etc/udev/rules.d/99-coolerdash.rules" "${pkgdir}/usr/lib/udev/rules.d/99-coolerdash.rules" + install -Dm644 "${srcdir}/${pkgname}/etc/icons/coolerdash.svg" "${pkgdir}/usr/share/icons/hicolor/scalable/apps/coolerdash.svg" + install -Dm644 "${srcdir}/${pkgname}/etc/systemd/coolerdash-helperd.service" "${pkgdir}/usr/lib/systemd/system/coolerdash-helperd.service" + install -Dm644 "${srcdir}/${pkgname}/etc/systemd/cc-plugin-coolerdash.service.d/startup-delay.conf" "${pkgdir}/etc/systemd/system/cc-plugin-coolerdash.service.d/startup-delay.conf" - install -Dm644 "${srcdir}/coolerdash/LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" + install -Dm644 "${srcdir}/${pkgname}/LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" } From 43fe90c47965a35695c61fd56d05ee67aa12f38d Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 24 Feb 2026 01:03:31 +0100 Subject: [PATCH 2/3] fix pkgbuild --- PKGBUILD | 2 +- aur/PKGBUILD | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PKGBUILD b/PKGBUILD index 4a7a1ae..2381770 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -33,7 +33,7 @@ build() { fi # Remove all previous tarball builds - rm -rf coolerdash-*.pkg.* + rm -f "${pkgname}"-*.pkg.tar.* # Clean any previous builds if a Makefile exists if [[ -f Makefile || -f GNUmakefile ]]; then diff --git a/aur/PKGBUILD b/aur/PKGBUILD index 763e5df..4913313 100644 --- a/aur/PKGBUILD +++ b/aur/PKGBUILD @@ -31,7 +31,7 @@ build() { cd "${srcdir}/${pkgname}" # Remove all previous tarball builds - rm -rf ${pkgname}-*.pkg.* + rm -f "${pkgname}"-*.pkg.tar.* # Clean any previous builds if a Makefile exists if [[ -f Makefile || -f GNUmakefile ]]; then From 15348bd633ae07699dc02d22b84f90eee68a2319 Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 24 Feb 2026 01:57:14 +0100 Subject: [PATCH 3/3] docs: Update coolerdash documentation --- .SRCINFO | 2 +- aur/PKGBUILD | 8 +- docs/config-guide.md | 669 ++++-------------- docs/coolercontrol-api.md | 19 +- docs/developer-guide.md | 324 ++++----- docs/devices.md | 5 +- docs/display-detection.md | 61 +- docs/display-modes.md | 124 ++-- docs/plugin-integration.md | 6 +- docs/plugin-ui-theming.md | 4 +- .../plugins/coolerdash/ui/index.html | 12 +- 11 files changed, 366 insertions(+), 868 deletions(-) diff --git a/.SRCINFO b/.SRCINFO index 01a041e..bcc031c 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,6 +1,6 @@ pkgbase = coolerdash pkgdesc = Monitor telemetry data on an AIO liquid cooler with an integrated LCD display - pkgver = 2.2.5 + pkgver = 2.2.6 pkgrel = 1 url = https://github.com/damachine/coolerdash install = coolerdash.install diff --git a/aur/PKGBUILD b/aur/PKGBUILD index 4913313..a08dfc4 100644 --- a/aur/PKGBUILD +++ b/aur/PKGBUILD @@ -16,11 +16,11 @@ makedepends=('gcc' 'make' 'pkg-config' 'git') backup=('etc/coolercontrol/plugins/coolerdash/config.json') install=coolerdash.install _commit= -source=("git+https://github.com/damachine/coolerdash.git#commit=${_commit}") +source=("coolerdash-git::git+https://github.com/damachine/coolerdash.git#commit=${_commit}") sha256sums=('SKIP') # SKIP for git repo source builds pkgver() { - cd "${srcdir}/${pkgname}" + cd "${srcdir}"/"${pkgname}" # Fetch latest tags in git repo git fetch --tags git describe --tags --long --match "v*" | sed -E 's/^v//; s/-([0-9]+)-g/\.r\1.g/; s/-/./g' @@ -28,7 +28,7 @@ pkgver() { build() { # Build inside the checked-out repository - cd "${srcdir}/${pkgname}" + cd "${srcdir}"/"${pkgname}" # Remove all previous tarball builds rm -f "${pkgname}"-*.pkg.tar.* @@ -44,7 +44,7 @@ build() { check() { # Check in the checked-out repository - cd "${srcdir}/${pkgname}" + cd "${srcdir}"/"${pkgname}" # Verify that the binary was created successfully if [[ -f bin/coolerdash ]]; then diff --git a/docs/config-guide.md b/docs/config-guide.md index eef916b..a3276f8 100644 --- a/docs/config-guide.md +++ b/docs/config-guide.md @@ -1,32 +1,32 @@ # CoolerDash Configuration Guide -Complete guide for configuring CoolerDash through the `config.ini` file. +Complete guide for configuring CoolerDash through the `config.json` file. -## ๐Ÿ“ Configuration File Location +## Configuration File Location -The configuration file is located at: ``` -/etc/coolerdash/config.ini +/etc/coolercontrol/plugins/coolerdash/config.json ``` -## ๐Ÿ”„ Applying Changes +## Applying Changes -After modifying the configuration file, restart CoolerDash: +Restaring CoolerControl reloads the plugin and picks up config changes: ```bash -sudo systemctl restart coolerdash +sudo systemctl restart coolercontrold ``` --- -## ๐ŸŒ Daemon Settings +## Daemon Settings -Configure connection to CoolerControl daemon API. +Configure connection to the CoolerControl daemon API. -### Example Configuration -```ini -[daemon] -address=http://localhost:11987 -password=coolAdmin +### Example +```json +"daemon": { + "address": "http://localhost:11987", + "password": "coolAdmin" +} ``` ### Settings @@ -34,33 +34,32 @@ password=coolAdmin - **`password`**: API authentication password (default: `coolAdmin`) ### HTTPS Example -For secure connections: -```ini -[daemon] -address=https://192.168.1.100:11987 -password=mySecurePassword123 +```json +"daemon": { + "address": "https://192.168.1.100:11987", + "password": "mySecurePassword123" +} ``` --- -## ๐Ÿ“ File Paths +## File Paths System file and directory locations. -### Example Configuration -```ini -[paths] -images=/etc/coolercontrol/plugins/coolerdash -image_coolerdash=/etc/coolercontrol/plugins/coolerdash/coolerdash.png -image_shutdown=/etc/coolercontrol/plugins/coolerdash/shutdown.png -pid=/tmp/coolerdash.pid +### Example +```json +"paths": { + "images": "/etc/coolercontrol/plugins/coolerdash", + "image_coolerdash": "/etc/coolercontrol/plugins/coolerdash/coolerdash.png", + "image_shutdown": "/etc/coolercontrol/plugins/coolerdash/shutdown.png" +} ``` ### Settings -- **`images`**: Directory containing display images +- **`images`**: Directory for generated display images - **`image_coolerdash`**: Generated display image path -- **`image_shutdown`**: Shutdown screen image -- **`pid`**: Process ID file location +- **`image_shutdown`**: Image displayed on daemon shutdown --- @@ -69,62 +68,46 @@ pid=/tmp/coolerdash.pid LCD display configuration tested with NZXT Kraken 2023. ### Basic Configuration -```ini -[display] -width=240 -height=240 -refresh_interval=2.50 -brightness=80 -orientation=0 -shape=auto -mode=dual -circle_switch_interval=5 -content_scale_factor=0.98 - -# Optional: Custom inscribe factor for circular displays -# - Range: >=0 && <=1.0 -# - 0.0 means "auto" (use geometric inscribe factor 1/โˆš2 โ‰ˆ 0.7071) -# - Default: 0.70710678 (geometric inscribe) -# - Example values: 0.70710678 (geometric), 0.85 (more usable area) -# inscribe_factor=0.70710678 -``` +```json +"display": { + "mode": "dual", + "width": 0, + "height": 0, + "refresh_interval": 2.5, + "brightness": 80, + "orientation": 0, + "shape": "auto", + "circle_switch_interval": 5, + "content_scale_factor": 0.98, + "inscribe_factor": 0.70710678 +} +``` + +> `width`/`height` set to `0` means CoolerDash queries the actual device dimensions from the API at startup. ### Settings -- **`width`**: Screen width in pixels (240 for NZXT Kraken) -- **`height`**: Screen height in pixels (240 for NZXT Kraken) -- **`refresh_interval`**: Update interval in seconds with 2 decimal places (0.01-60.0, default: 2.50) -- **`brightness`**: LCD brightness 0-100% (80% recommended) -- **`orientation`**: Screen rotation: `0`, `90`, `180`, `270` degrees -- **`shape`**: Display shape override: `auto` (default), `rectangular`, or `circular` - **`mode`**: Display mode: `dual` (default) or `circle` -- **`circle_switch_interval`**: Circle mode sensor switch interval in seconds (1-60, default: 5) -- **`content_scale_factor`**: Content scale factor (0.5-1.0, default: 0.98) - percentage of safe area used for content +- **`width`** / **`height`**: Screen dimensions in pixels; `0` = auto-detect from API +- **`refresh_interval`**: Update interval in seconds (0.01โ€“60.0, default: `2.5`) +- **`brightness`**: LCD brightness 0โ€“100% (default: `80`) +- **`orientation`**: Screen rotation: `0`, `90`, `180`, `270` degrees +- **`shape`**: Display shape: `auto` (default), `rectangular`, or `circular` +- **`circle_switch_interval`**: Slot switch interval for circle mode in seconds (1โ€“60, default: `5`) +- **`content_scale_factor`**: Safe area percentage (0.5โ€“1.0, default: `0.98`) +- **`inscribe_factor`**: Inscribe factor for circular displays (default: `0.70710678` = 1/โˆš2) ### Brightness Examples -```ini -# Dim for night use -brightness=40 - -# Standard brightness (recommended) -brightness=80 - -# Maximum brightness -brightness=100 +```json +"brightness": 40, // dim for night use +"brightness": 80, // recommended default +"brightness": 100 // maximum ``` ### Refresh Rate Examples -```ini -# Fast updates (1 second) -refresh_interval=1.00 - -# Standard updates (2.5 seconds) - default -refresh_interval=2.50 - -# Moderate updates (3.5 seconds) -refresh_interval=3.50 - -# Slow updates (5 seconds) - saves power -refresh_interval=5.00 +```json +"refresh_interval": 1.0, // fast +"refresh_interval": 2.5, // default +"refresh_interval": 5.0 // power-saving ``` ### Display Shape Override @@ -141,18 +124,13 @@ The `shape` parameter allows manual control of the **inscribe factor** used for - Overriding auto-detection if it's incorrect for your device **Examples:** -```ini -# Auto-detection (recommended) -shape=auto - -# Force rectangular layout (full width, inscribe factor = 1.0) -shape=rectangular - -# Force circular layout (inscribed square, inscribe factor = 0.7071) -shape=circular +```json +"shape": "auto" // recommended +"shape": "rectangular" // full width, inscribe_factor = 1.0 +"shape": "circular" // inscribed square, inscribe_factor = 0.7071 ``` -**Priority:** `shape` config > `--force-display-circular` CLI flag > auto-detection +**Priority:** `shape` config > auto-detection **Note:** See [Display Detection Guide](display-detection.md) for technical details about inscribe factors. @@ -167,10 +145,9 @@ Controls how frequently the circle mode rotates between available sensors: - **Applies to:** Circle mode only **Example:** -```ini -[display] -mode=circle -circle_switch_interval=10 # Switch every 10 seconds +```json +"mode": "circle", +"circle_switch_interval": 10 ``` **Use Cases:** @@ -189,9 +166,8 @@ Controls the safe area percentage used for rendering content (determines margin/ - **Applies to:** Both dual and circle modes **Example:** -```ini -[display] -content_scale_factor=0.95 # 5% margin for more padding +```json +"content_scale_factor": 0.95 ``` **Use Cases:** @@ -221,494 +197,97 @@ bar_border=2.0 ### Settings - **`bar_height`**: Temperature bar thickness in pixels (default: auto-scaled) -- **`bar_width`**: Bar width as percentage of display width (1-100%, default: 98%) - - 98% = 1% margin left + 1% margin right - - 50% = centered bar with 25% margin on each side - - 100% = full width, no margins -- **`bar_gap`**: Space between temperature bars in pixels (default: auto-scaled) -- **`bar_border`**: Border line thickness in pixels (default: 1.0) +- **`bar_width`**: Bar width in percent of display width (1โ€“100%, default: 98) +- **`bar_gap`**: Gap between bars in pixels (default: auto-scaled) +- **`bar_border`**: Border thickness in pixels (default: 1.0) ### Layout Examples -#### Compact Layout -```ini -[layout] -bar_height=18 -bar_width=90 -bar_gap=5 -bar_border=1.0 -``` - -#### Spacious Layout -```ini -[layout] -bar_height=26 -bar_width=98 -bar_gap=15 -bar_border=2.0 -``` - -#### Custom Width Example (Centered) -```ini -[layout] -bar_height=24 -bar_width=60 # 60% width = 20% margin on each side -bar_gap=12 -bar_border=1.5 -``` - ---- - -## ๐ŸŽจ Colors - -RGB color configuration (values 0-255). - -### Bar Colors -```ini -[bar_color_background] -r=52 # Dark gray -g=52 -b=52 - -[bar_color_border] -r=192 # Light gray -g=192 -b=192 -``` - -### Color Examples - -#### Dark Theme -```ini -[bar_color_background] -r=25 # Very dark gray -g=25 -b=25 - -[bar_color_border] -r=100 # Medium gray -g=100 -b=100 -``` - -#### Blue Theme -```ini -[bar_color_background] -r=20 # Dark blue -g=30 -b=60 - -[bar_color_border] -r=70 # Light blue -g=130 -b=180 -``` +```json +// Compact +"layout": { "bar_height": 18, "bar_width": 90, "bar_gap": 5, "bar_border": 1.0 } -#### Custom RGB Colors -```ini -# Pure black background -[bar_color_background] -r=0 -g=0 -b=0 - -# White border -[bar_color_border] -r=255 -g=255 -b=255 +// Spacious +"layout": { "bar_height": 26, "bar_width": 98, "bar_gap": 15, "bar_border": 2.0 } ``` --- -## ๐Ÿ”ค Font Settings - -Text appearance configuration with automatic display-size-dependent defaults. - -### Example Configuration -```ini -[font] -font_face=Roboto Black -font_size_temp=100.0 -font_size_labels=30.0 - -[font_color_temp] -r=255 # White temperature text -g=255 -b=255 - -[font_color_label] -r=200 # Light gray labels -g=200 -b=200 -``` - -### Settings -- **`font_face`**: Font family name (must be installed on system, default: Roboto Black) -- **`font_size_temp`**: Temperature number size in points - - **Dynamic defaults** based on display resolution: - - 240x240: 100.0pt (base size) - - 320x320: 133.3pt (automatically scaled) - - 480x480: 200.0pt (automatically scaled) - - Formula: `100.0 ร— ((width + height) / (2 ร— 240.0))` -- **`font_size_labels`**: CPU/GPU label size in points - - **Dynamic defaults** based on display resolution: - - 240x240: 30.0pt (base size) - - 320x320: 40.0pt (automatically scaled) - - 480x480: 60.0pt (automatically scaled) - - Formula: `30.0 ร— ((width + height) / (2 ร— 240.0))` - -**Note:** If you set custom values in config.ini, they override the automatic scaling. - -### Font Examples - -#### Large Text Setup (Manual Override) -```ini -[font] -font_face=Arial Bold -font_size_temp=150.0 # Override auto-scaling with fixed large size -font_size_labels=45.0 # Override auto-scaling -``` - -#### Compact Text Setup (Manual Override) -```ini -[font] -font_face=Helvetica -font_size_temp=80.0 # Override auto-scaling with fixed small size -font_size_labels=24.0 # Override auto-scaling -``` +## Colors -#### Use Auto-Scaling (Recommended) -```ini -[font] -font_face=Roboto Black -# Comment out or remove font_size_* lines to use automatic scaling -# ;font_size_temp=100.0 # Automatically scaled based on display size -# ;font_size_labels=30.0 # Automatically scaled based on display size -``` +RGB color values (0โ€“255). -#### Color Examples -```ini -# Bright white text -[font_color_temp] -r=255 -g=255 -b=255 - -# Cyan labels -[font_color_label] -r=0 -g=255 -b=255 +```json +"colors": { + "bar_background": { "r": 52, "g": 52, "b": 52 }, + "bar_border": { "r": 192, "g": 192, "b": 192 }, + "font_temp": { "r": 255, "g": 255, "b": 255 }, + "font_label": { "r": 200, "g": 200, "b": 200 } +} ``` --- -## ๐ŸŒก๏ธ Temperature Zones - -Color-coded temperature thresholds and their colors. - -### Example Configuration -```ini -[temperature] -temp_threshold_1=55.0 # Cool zone (< 55ยฐC) -temp_threshold_2=65.0 # Warm zone (55-65ยฐC) -temp_threshold_3=75.0 # Hot zone (65-75ยฐC) - # Critical zone (> 75ยฐC) - -[temp_threshold_1_bar] # ๐Ÿ’š Cool (Green) -r=0 -g=255 -b=0 - -[temp_threshold_2_bar] # ๐Ÿงก Warm (Orange) -r=255 -g=140 -b=0 - -[temp_threshold_3_bar] # ๐Ÿ”ฅ Hot (Dark Orange) -r=255 -g=70 -b=0 - -[temp_threshold_4_bar] # ๐Ÿšจ Critical (Red) -r=255 -g=0 -b=0 -``` - -### Temperature Threshold Examples +## Font Settings -#### Conservative (Lower Thresholds) -```ini -[temperature] -temp_threshold_1=45.0 # Cool < 45ยฐC -temp_threshold_2=55.0 # Warm 45-55ยฐC -temp_threshold_3=65.0 # Hot 55-65ยฐC - # Critical > 65ยฐC -``` - -#### Aggressive (Higher Thresholds) -```ini -[temperature] -temp_threshold_1=60.0 # Cool < 60ยฐC -temp_threshold_2=70.0 # Warm 60-70ยฐC -temp_threshold_3=80.0 # Hot 70-80ยฐC - # Critical > 80ยฐC -``` - -### Color Scheme Examples - -#### Rainbow Theme -```ini -[temp_threshold_1_bar] # Blue (Cool) -r=0 -g=100 -b=255 - -[temp_threshold_2_bar] # Yellow (Warm) -r=255 -g=255 -b=0 - -[temp_threshold_3_bar] # Orange (Hot) -r=255 -g=128 -b=0 - -[temp_threshold_4_bar] # Red (Critical) -r=255 -g=0 -b=0 +```json +"font": { + "face": "Roboto Black", + "size_temp": 0, + "size_labels": 0 +} ``` -#### Monochrome Theme -```ini -[temp_threshold_1_bar] # Light gray -r=200 -g=200 -b=200 - -[temp_threshold_2_bar] # Medium gray -r=150 -g=150 -b=150 - -[temp_threshold_3_bar] # Dark gray -r=100 -g=100 -b=100 - -[temp_threshold_4_bar] # Very dark gray -r=50 -g=50 -b=50 -``` +- **`face`**: Font family name (must be installed, default: `Roboto Black`) +- **`size_temp`** / **`size_labels`**: Font size in points. `0` = auto-scale based on display resolution + - 240ร—240: ~100pt temp / ~30pt labels + - Formula: `100.0 ร— (width + height) / (2 ร— 240.0)` --- -## ๐Ÿ“‹ Complete Example Configuration - -Here's a complete working configuration file: - -```ini -# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• -# CoolerDash Configuration - NZXT Kraken Setup -# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• - -[daemon] -address=http://localhost:11987 -password=coolAdmin - -[paths] -images=/etc/coolercontrol/plugins/coolerdash -image_coolerdash=/etc/coolercontrol/plugins/coolerdash/coolerdash.png -image_shutdown=/etc/coolercontrol/plugins/coolerdash/shutdown.png -pid=/tmp/coolerdash.pid - -[display] -width=240 -height=240 -refresh_interval=2.50 -brightness=80 -orientation=0 -shape=auto -mode=dual -circle_switch_interval=5 -content_scale_factor=0.98 +## Temperature Zones -[layout] -bar_height=24 -bar_width=98 -bar_gap=12 -bar_border=2.0 +Four color zones based on temperature thresholds. Configured per-sensor in the `sensors` section. -[bar_color_background] -r=52 -g=52 -b=52 - -[bar_color_border] -r=192 -g=192 -b=192 - -[font] -font_face=Roboto Black -font_size_temp=100.0 -font_size_labels=30.0 - -[font_color_temp] -r=255 -g=255 -b=255 - -[font_color_label] -r=200 -g=200 -b=200 - -[temperature] -temp_threshold_1=55.0 -temp_threshold_2=65.0 -temp_threshold_3=75.0 - -[temp_threshold_1_bar] -r=0 -g=255 -b=0 - -[temp_threshold_2_bar] -r=255 -g=140 -b=0 - -[temp_threshold_3_bar] -r=255 -g=70 -b=0 - -[temp_threshold_4_bar] -r=255 -g=0 -b=0 +```json +"sensors": { + "cpu": { + "threshold_1": 55.0, + "threshold_2": 65.0, + "threshold_3": 75.0, + "threshold_1_bar": { "r": 0, "g": 255, "b": 0 }, + "threshold_2_bar": { "r": 255, "g": 140, "b": 0 }, + "threshold_3_bar": { "r": 255, "g": 70, "b": 0 }, + "threshold_4_bar": { "r": 255, "g": 0, "b": 0 } + } +} ``` --- -## ๐ŸŽฏ Advanced: Manual Position Offsets - -Fine-tune element positions with pixel-level precision. All values are in pixels. - -### Example Configuration -```ini -[display_positioning] -# Temperature numbers (CPU and GPU independent) -display_temp_offset_x=0,0 # Horizontal offset (single value=both, "cpu,gpu"=separate) -display_temp_offset_y=0,0 # Vertical offset (single value=both, "cpu,gpu"=separate) - -# Degree symbol spacing -display_degree_spacing=16 # Distance from temperature number (default: 16px) - -# CPU/GPU labels -display_label_offset_x=0 # Horizontal offset (+right, -left) -display_label_offset_y=0 # Vertical offset (+down, -up) -``` - -### Temperature Offsets - -Control CPU and GPU temperature number positions independently: - -```ini -# Both temperatures the same -display_temp_offset_x=15 # Both CPU+GPU 15px right -display_temp_offset_y=-10 # Both CPU+GPU 10px up - -# CPU and GPU different (comma-separated) -display_temp_offset_x=20,-5 # CPU: 20px right, GPU: 5px left -display_temp_offset_y=10,-10 # CPU: 10px down, GPU: 10px up -``` - -**Behavior:** -- `-9999` or commented out = auto positioning (default) -- Single value = applies to both CPU and GPU -- Comma-separated = individual CPU,GPU values -- Positive = right/down, Negative = left/up -- Degree symbol moves with temperature (bound together) - -### Degree Symbol Spacing - -Adjust distance between temperature number and degree symbol: - -```ini -display_degree_spacing=10 # Closer: 10px -display_degree_spacing=20 # Wider: 20px -display_degree_spacing=16 # Default: 16px -``` - -### Label Offsets - -Adjust CPU/GPU label positions: - -```ini -display_label_offset_x=5 # 5px right -display_label_offset_y=-3 # 3px up -display_label_offset_x=-10 # 10px left -``` - -### Use Cases - -**Dual Mode Fine-Tuning:** -```ini -# Shift CPU temp slightly up, GPU slightly down -display_temp_offset_y=-5,5 -``` - -**Circle Mode Adjustments:** -```ini -# CPU display uses first value, GPU display uses second -display_temp_offset_x=10,15 # CPU: +10px, GPU: +15px -``` +## Complete Example -**Tighter Layout:** -```ini -display_degree_spacing=8 # Closer degree symbol -display_label_offset_x=-5 # Labels closer to edge -``` +See the default config at `/etc/coolercontrol/plugins/coolerdash/config.json` for a full reference. The file is installed with all options and their defaults. --- -## ๐Ÿ”ง Troubleshooting - -### Common Issues +## Troubleshooting -1. **Display not updating**: Check refresh intervals and restart service -2. **Wrong colors**: Verify RGB values are 0-255 -3. **Text too small/large**: Adjust font_size_temp and font_size_labels (or remove them for auto-scaling) -4. **Bars too wide/narrow**: Adjust bar_width percentage (1-100%, default: 98%) -5. **Content clipped on circular displays**: Check inscribe_factor and content_scale_factor settings - -### Testing Changes - -Always restart the service after configuration changes: -```bash -sudo systemctl restart coolerdash -sudo systemctl status coolerdash -``` +1. **Display not updating**: Check `refresh_interval` and restart CoolerControl +2. **Wrong colors**: Verify RGB values are 0โ€“255 +3. **Text clipped on circular display**: Adjust `inscribe_factor` and `content_scale_factor` +4. **Bars too wide**: Lower `bar_width` value -### Backup Configuration +### Backup -Before making changes, backup your working configuration: ```bash -sudo cp /etc/coolerdash/config.ini /etc/coolerdash/config.ini.backup +sudo cp /etc/coolercontrol/plugins/coolerdash/config.json \ + /etc/coolercontrol/plugins/coolerdash/config.json.backup ``` -## ๐Ÿงช Run scaling unit test (developer) +## Developer: Scaling Unit Test -There is a small test harness that validates safe_area and safe_bar calculations used by the renderers. -Build and run the test with: ```bash gcc -std=c99 -Iinclude -I./src -o build/test_scaling tests/test_scaling.c -lm ./build/test_scaling ``` -This will print the computed safe_area and safe_bar width for representative cases: auto (0.0), explicit 0.70710678 and custom 0.85. diff --git a/docs/coolercontrol-api.md b/docs/coolercontrol-api.md index 58172eb..786cd26 100644 --- a/docs/coolercontrol-api.md +++ b/docs/coolercontrol-api.md @@ -78,8 +78,9 @@ PUT /devices/{uid}/settings/lcd/... - LCD image upload ### Initialization Sequence ```c -// 1. Configuration loading (usr.c, sys.c) -Config config = load_configuration(); +// 1. Configuration loading (config.c) +Config config = {0}; +load_plugin_config(&config, CONFIG_PATH); // 2. CoolerControl session initialization init_coolercontrol_session(&config); @@ -93,7 +94,7 @@ update_config_from_device(&config); // 5. Main loop: fetch data โ†’ render โ†’ upload while (running) { get_temperature_monitor_data(&config, &data); - draw_combined_image(&config); // Renders to PNG + draw_display_image(&config); // Dispatches to dual or circle mode // send_image_to_lcd() called internally sleep(update_interval); } @@ -627,7 +628,7 @@ force_circular = true **Function**: `update_config_from_device(Config *config)` -**Purpose**: Update config with device screen dimensions (only if not set in config.ini) +**Purpose**: Update config with device screen dimensions (only if not set in `config.json`) **Logic**: ```c @@ -636,7 +637,7 @@ int update_config_from_device(Config *config) if (!config) return 0; - // Only update if config.ini values are 0 (commented out) + // Only update if config.json values are 0 (auto-detect) if (config->display_width == 0) { config->display_width = device_cache.screen_width; log_message(LOG_INFO, "Updated display width to %d from device", @@ -653,7 +654,7 @@ int update_config_from_device(Config *config) } ``` -**Use Case**: Auto-detect display resolution when user doesn't specify in config.ini +**Use Case**: Auto-detect display resolution when user doesn't specify in `config.json` #### 6. Safe String Copy @@ -994,7 +995,7 @@ while (running) โ”‚ โ””โ”€โ†’ Parse: Extract temp_cpu and temp_gpu โ†“ -2. draw_combined_image(&config) +2. draw_display_image(&config) โ”‚ โ”œโ”€โ†’ render_dual_display() or render_circle_display() โ”‚ โ”‚ @@ -1149,7 +1150,7 @@ log_message(LOG_ERROR, "Login failed: CURL code %d, HTTP code %ld", res, respons **Resolution**: - Verify daemon is running: `systemctl status coolercontrol` -- Check password in config.ini +- Check password in `config.json` - Test connection: `curl http://127.0.0.1:11987/devices` #### 2. Device Not Found @@ -1574,7 +1575,7 @@ while (running) { monitor_sensor_data_t data = {0}; if (get_temperature_monitor_data(&config, &data)) { // Render and upload handled by display modules - draw_combined_image(&config); + draw_display_image(&config); } sleep(2); } diff --git a/docs/developer-guide.md b/docs/developer-guide.md index cb455f2..8f6e6f3 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -1,11 +1,7 @@ # CoolerDash Developer Documentation -**Project:** CoolerDash - LCD Display Enhancement for CoolerControl -**Version:** 1.94+ -**Language:** C99 -**Platform:** Linux (x86-64-v3) -**License:** MIT -**Author:** damachine (christkue79@gmail.com) +**Language:** C99 | **Platform:** Linux x86-64-v3 | **License:** MIT +**Author:** damachine (damachin3@proton.me) **Repository:** https://github.com/damachine/coolerdash --- @@ -42,15 +38,14 @@ CoolerDash extends the LCD functionality of [CoolerControl](https://gitlab.com/c ### System Requirements -- **OS:** Linux (systemd-based distributions) +- **OS:** Linux (systemd-based) - **Architecture:** x86-64-v3 (Intel Haswell+ / AMD Excavator+) - **Dependencies:** - - **cairo** - Graphics rendering (PNG generation) - - **jansson** - JSON parsing (API responses) - - **libcurl-gnutls** - HTTP client (REST API communication) - - **libinih** - INI file parsing (configuration) - - **ttf-roboto** - Font rendering -- **Required Service:** CoolerControl >=2.2.2 (must be running) + - `cairo` โ€” PNG generation + - `jansson` โ€” JSON parsing (config + API) + - `libcurl-gnutls` โ€” HTTP client + - `ttf-roboto` โ€” Font rendering +- **Required Service:** CoolerControl >=3.x (must be running) --- @@ -62,15 +57,15 @@ CoolerDash extends the LCD functionality of [CoolerControl](https://gitlab.com/c โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ main.c โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ -โ”‚ โ”‚ 1. Configuration Loading (usr.c + sys.c) โ”‚ โ”‚ +โ”‚ โ”‚ 1. Configuration Loading (device/config.c) โ”‚ โ”‚ โ”‚ โ”‚ 2. Session Initialization (cc_main.c) โ”‚ โ”‚ โ”‚ โ”‚ 3. Device Cache Setup (cc_conf.c) โ”‚ โ”‚ -โ”‚ โ”‚ 4. Main Loop (60s interval) โ”‚ โ”‚ +โ”‚ โ”‚ 4. Main Loop (configurable interval) โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€ Temperature Reading (cc_sensor.c) โ”‚ โ”‚ -โ”‚ โ”‚ โ”œโ”€ Image Rendering (dual.c) โ”‚ โ”‚ +โ”‚ โ”‚ โ”œโ”€ Image Rendering (display.c โ†’ dual.c|circle.c) โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€ LCD Upload (cc_main.c) โ”‚ โ”‚ โ”‚ โ”‚ 5. Signal Handling (SIGTERM/SIGINT โ†’ shutdown image) โ”‚ โ”‚ -โ”‚ โ”‚ 6. Cleanup (session + PID file removal) โ”‚ โ”‚ +โ”‚ โ”‚ 6. Cleanup (session + image files) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ†“ โ†“ โ†“ @@ -79,9 +74,9 @@ CoolerDash extends the LCD functionality of [CoolerControl](https://gitlab.com/c โ”‚ Configuration โ”‚ โ”‚ CoolerControl โ”‚ โ”‚ Rendering โ”‚ โ”‚ Management โ”‚ โ”‚ API Client โ”‚ โ”‚ Engine โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - sys.c/h cc_main.c/h dual.c/h - usr.c/h cc_conf.c/h - cc_sensor.c/h + config.c/h cc_main.c/h display.c/h + cc_conf.c/h dual.c/h + cc_sensor.c/h circle.c/h ``` ### Design Principles @@ -103,16 +98,17 @@ coolerdash/ โ”œโ”€โ”€ src/ โ”‚ โ”œโ”€โ”€ main.c # Main daemon entry point (967 lines, 30 functions) โ”‚ โ”œโ”€โ”€ device/ # Configuration subsystem -โ”‚ โ”‚ โ”œโ”€โ”€ sys.c/h # System defaults (295 lines, 11 functions) -โ”‚ โ”‚ โ””โ”€โ”€ usr.c/h # User INI parsing (584 lines, 25+ functions) +โ”‚ โ”‚ โ””โ”€โ”€ config.c/h # JSON config loader + defaults โ”‚ โ”œโ”€โ”€ srv/ # CoolerControl API client -โ”‚ โ”‚ โ”œโ”€โ”€ cc_main.c/h # Session management (549 lines, 19 functions) -โ”‚ โ”‚ โ”œโ”€โ”€ cc_conf.c/h # Device cache (467 lines, 20 functions) -โ”‚ โ”‚ โ””โ”€โ”€ cc_sensor.c/h # Temperature monitoring (298 lines, 6 functions) +โ”‚ โ”‚ โ”œโ”€โ”€ cc_main.c/h # Session management +โ”‚ โ”‚ โ”œโ”€โ”€ cc_conf.c/h # Device cache, display detection +โ”‚ โ”‚ โ””โ”€โ”€ cc_sensor.c/h # Temperature monitoring โ”‚ โ””โ”€โ”€ mods/ # Rendering modules -โ”‚ โ””โ”€โ”€ dual.c/h # Cairo-based LCD rendering (576 lines, 15+ functions) +โ”‚ โ”œโ”€โ”€ display.c/h # Mode dispatcher, shared helpers +โ”‚ โ”œโ”€โ”€ dual.c/h # Dual mode (CPU+GPU simultaneous) +โ”‚ โ””โ”€โ”€ circle.c/h # Circle mode (alternating sensor) โ”œโ”€โ”€ etc/ -โ”‚ โ”œโ”€โ”€ coolerdash/config.ini # User configuration +โ”‚ โ”œโ”€โ”€ coolercontrol/plugins/coolerdash/config.json # User configuration โ”‚ โ””โ”€โ”€ systemd/coolerdash.service โ”œโ”€โ”€ docs/ # Documentation โ”‚ โ”œโ”€โ”€ config.md # Configuration guide @@ -126,13 +122,14 @@ coolerdash/ | Module | Purpose | Key Functions | Lines | Public API | |--------|---------|---------------|-------|------------| -| **main.c** | Daemon lifecycle | Signal handling, PID management, main loop | 967 | `main()` | -| **device/sys** | Default config | Hardcoded fallback values | 295 | `init_system_defaults()` | -| **device/usr** | User config | INI parsing with change tracking | 584 | `load_user_config()` | -| **srv/cc_main** | HTTP session | Login, LCD upload, cleanup | 549 | 4 functions | -| **srv/cc_conf** | Device cache | UID/name/dimensions, display shape | 467 | 4 functions | -| **srv/cc_sensor** | Temperature | CPU/GPU sensor reading | 298 | 1 function | -| **mods/dual** | Rendering | Cairo PNG generation | 576 | 2 functions | +| **main.c** | Daemon lifecycle | Signal handling, PID management, main loop | โ€” | `main()` | +| **device/config** | Config system | JSON loading, hardcoded defaults | โ€” | `load_plugin_config()` | +| **srv/cc_main** | HTTP session | Login, LCD upload, cleanup | โ€” | 4 functions | +| **srv/cc_conf** | Device cache | UID/name/dimensions, display shape | โ€” | 4 functions | +| **srv/cc_sensor** | Temperature | CPU/GPU sensor reading | โ€” | 1 function | +| **mods/display** | Mode dispatch | Route to dual/circle, shared Cairo helpers | โ€” | `draw_display_image()` | +| **mods/dual** | Dual rendering | CPU+GPU simultaneous layout | โ€” | `draw_dual_image()` | +| **mods/circle** | Circle rendering | Alternating single-sensor layout | โ€” | `draw_circle_image()` | --- @@ -159,8 +156,8 @@ make help # Show all available targets ```makefile CFLAGS = -Wall -Wextra -O2 -std=c99 -march=x86-64-v3 -Iinclude \ - $(shell pkg-config --cflags cairo jansson libcurl inih) -LIBS = $(shell pkg-config --libs cairo jansson libcurl inih) -lm + $(shell pkg-config --cflags cairo jansson libcurl) +LIBS = $(shell pkg-config --libs cairo jansson libcurl) -lm ``` **Optimization Level:** `-O2` (production), `-O0` (debug) @@ -175,20 +172,19 @@ LIBS = $(shell pkg-config --libs cairo jansson libcurl inih) -lm โ”‚ โ”œโ”€ cairo (graphics) โ”‚ โ”‚ โ”œโ”€ jansson (JSON) โ”‚ โ”‚ โ”œโ”€ libcurl (HTTP) โ”‚ -โ”‚ โ””โ”€ inih (INI parsing) โ”‚ +โ”‚ โ””โ”€ jansson (JSON parsing) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ 2. Module Compilation (src/ โ†’ build/) โ”‚ -โ”‚ โ”œโ”€ device/sys.o, device/usr.o โ”‚ +โ”‚ โ”œโ”€ device/config.o โ”‚ โ”‚ โ”œโ”€ srv/cc_main.o, srv/cc_conf.o, srv/cc_sensor.o โ”‚ -โ”‚ โ””โ”€ mods/dual.o โ”‚ +โ”‚ โ””โ”€ mods/display.o, mods/dual.o, mods/circle.o โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ 3. Linking (main.c + modules โ†’ bin/coolerdash) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ 4. Installation (make install) โ”‚ -โ”‚ โ”œโ”€ Binary: /opt/coolerdash/bin/coolerdash โ”‚ -โ”‚ โ”œโ”€ Config: /etc/coolerdash/config.ini โ”‚ -โ”‚ โ”œโ”€ Service: /etc/systemd/system/coolerdash.service โ”‚ -โ”‚ โ”œโ”€ Symlink: /usr/bin/coolerdash โ”‚ +โ”‚ โ”œโ”€ Binary: /usr/libexec/coolerdash/coolerdash โ”‚ +โ”‚ โ”œโ”€ Config: /etc/coolercontrol/plugins/coolerdash/config.json โ”‚ +โ”‚ โ”œโ”€ Plugin UI: /etc/coolercontrol/plugins/coolerdash/ui/ โ”‚ โ”‚ โ””โ”€ Manual: /usr/share/man/man1/coolerdash.1 โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` @@ -203,33 +199,33 @@ LIBS = $(shell pkg-config --libs cairo jansson libcurl inih) -lm ## Configuration System -### Three-Stage Configuration Loading +### Two-Stage Configuration Loading ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ Stage 1: System Defaults (sys.c) โ”‚ -โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ -โ”‚ Hardcoded fallback values ensure all fields have valid defaults โ”‚ -โ”‚ Function: init_system_defaults(Config *config) โ”‚ -โ”‚ Example: daemon_address = "http://localhost:11987" โ”‚ +โ”‚ Stage 1: Hardcoded Defaults (device/config.c) โ”‚ +โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ +โ”‚ All Config fields initialized to built-in defaults โ”‚ +โ”‚ Function: set_*_defaults(Config *config) โ”‚ +โ”‚ Example: daemon_address = "http://localhost:11987" โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ Stage 2: User Overrides (usr.c) โ”‚ -โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ -โ”‚ Parse /etc/coolerdash/config.ini and override defaults โ”‚ -โ”‚ Function: load_user_config(const char *path, Config *config) โ”‚ -โ”‚ Change Tracking: Records all INI entries for verbose logging โ”‚ +โ”‚ Stage 2: JSON Config Override (device/config.c) โ”‚ +โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ +โ”‚ Parse config.json and override defaults โ”‚ +โ”‚ Function: load_plugin_config(Config *config, const char *path) โ”‚ +โ”‚ Path: /etc/coolercontrol/plugins/coolerdash/config.json โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ Stage 3: Device Detection (cc_conf.c) โ”‚ -โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ +โ”‚ Stage 3: Device API Detection (cc_conf.c) โ”‚ +โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ Auto-detect display dimensions from CoolerControl API โ”‚ -โ”‚ Function: update_config_from_device(Config *config) โ”‚ -โ”‚ Behavior: Only updates if config.ini values are 0 (commented) โ”‚ +โ”‚ Function: update_config_from_device(Config *config) โ”‚ +โ”‚ Behavior: Only updates if width/height are 0 in config โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ### Configuration Structure -**File:** `src/device/sys.h` +**File:** `src/device/config.h` ```c typedef struct { @@ -288,31 +284,21 @@ typedef struct { ### Change Tracking System -**Purpose:** Log all user customizations from config.ini to systemd journal for visibility +**Purpose:** Log active configuration to systemd journal at startup -**Implementation (usr.c):** +**Implementation (config.c):** ```c -#define MAX_CONFIG_CHANGES 100 -static ConfigChange config_changes[MAX_CONFIG_CHANGES]; -static int config_change_count = 0; - -// Called by INI parser for each entry -void record_config_change(const char *section, const char *key, const char *value); - -// Called after INI parsing completes - ALWAYS logs (no verbose flag required) -void log_config_changes(void); // Uses LOG_STATUS level (always visible) +// Called after JSON loading completes +void log_config(const Config *config); // Uses LOG_STATUS level (always visible) ``` **Example Output (always shown in systemd journal):** ``` -[CoolerDash STATUS] === User Configuration Changes (from coolerdash.ini) === -[CoolerDash STATUS] Found 3 customized configuration values: -[CoolerDash STATUS] [display] refresh_interval = 3.50 -[CoolerDash STATUS] [layout] bar_height = 33 -[CoolerDash STATUS] [temperature] temp_threshold_1 = 60.0 -[CoolerDash STATUS] === End of Configuration Changes === +[CoolerDash STATUS] Config loaded: mode=dual, interval=2.5s, brightness=80 +[CoolerDash STATUS] Display: 240x240, shape=auto +[CoolerDash STATUS] Daemon: http://localhost:11987 ``` **Note:** Changed from LOG_INFO to LOG_STATUS in version 1.96+ to ensure manual configuration changes are always visible in systemd journal, even without --verbose flag. @@ -494,16 +480,16 @@ Response: 200 OK ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ 1. draw_combined_image(config) โ”‚ +โ”‚ 1. draw_display_image(config) โ”‚ โ”‚ โ”œโ”€ Get device info from cache โ”‚ โ”‚ โ”œโ”€ Fetch temperature data (cc_sensor.c) โ”‚ -โ”‚ โ””โ”€ Call render_display() โ”‚ +โ”‚ โ””โ”€ Dispatch to draw_dual_image() or draw_circle_image() โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ 2. render_display(config, data, device_name) โ”‚ โ”‚ โ”œโ”€ Detect display shape (circular vs rectangular) โ”‚ โ”‚ โ”œโ”€ Calculate scaling parameters โ”‚ โ”‚ โ”‚ โ”œโ”€ Circular: inscribe_factor = 1/โˆš2 (โ‰ˆ0.7071, default) -โ”‚ โ”‚ โ”‚ * Can be overridden in `config.ini` with `inscribe_factor` (>=0; 0 = auto) +โ”‚ โ”‚ โ”‚ * Can be overridden in `config.json` with `inscribe_factor` (>=0; 0 = auto) โ”‚ โ”‚ โ””โ”€ Rectangular: inscribe_factor = 1.0 โ”‚ โ”‚ โ”œโ”€ Create Cairo surface (width ร— height ร— ARGB32) โ”‚ โ”‚ โ”œโ”€ Draw background โ”‚ @@ -678,47 +664,35 @@ int calculate_temp_fill_width(float temp, int max_width, float max_temp) { --- -### Module: device/sys.c (System Defaults) +### Module: device/config.c (Configuration System) | Function | Purpose | |----------|---------| -| `init_system_defaults(config)` | Initialize all fields with hardcoded defaults | -| `apply_system_defaults(config)` | Fill missing fields after user config load | +| `load_plugin_config(config, path)` | Load JSON config, apply defaults, log result | +| `set_*_defaults(config)` | Initialize subsystem fields with hardcoded defaults | | `log_message(level, format, ...)` | Global logging function (respects verbose flag) | -**Default Values Example:** +**Default Values:** ```c daemon_address = "http://localhost:11987" daemon_password = "coolAdmin" -display_width = 0 // Auto-detected from API -display_refresh_interval = 2.50 // 2.5 seconds +display_width = 0 // auto-detected from API +display_refresh_interval = 2.5 lcd_brightness = 80 -temp_cpu_high = 80.0 ``` ---- - -### Module: device/usr.c (User Configuration) - -| Function | Purpose | -|----------|---------| -| `load_user_config(path, config)` | Parse INI file, record changes, log if verbose | -| `parse_config_data(section, name, value, config)` | INI handler callback | -| `record_config_change()` | Store section/key/value for verbose logging | -| `log_config_changes()` | Print all recorded changes if verbose enabled | +**JSON Sections:** -**INI Sections:** - -``` -[daemon] โ†’ daemon_address, daemon_password -[paths] โ†’ paths_images, paths_pid, etc. -[display] โ†’ width, height, brightness, orientation, refresh_interval -[layout] โ†’ bar_height, label_size, value_size, content_y_offset -[font] โ†’ face, weight_label, weight_value -[temperature] โ†’ cpu_low, cpu_medium, cpu_high, gpu_* -[color_*] โ†’ 15 color sections (background, cpu_label, etc.) -``` +```json +{ + "daemon": { "address": "...", "password": "..." }, + "display": { "width": 0, "height": 0, "brightness": 80, "mode": "dual" }, + "layout": { "bar_height": 30, "label_size": 18, "value_size": 24 }, + "font": { "face": "Roboto" }, + "temperature": { "cpu_low": 50, "cpu_medium": 70, "cpu_high": 85 }, + "colors": { "background": [0,0,0], "cpu_label": [255,255,255] } +} --- @@ -834,16 +808,17 @@ if (temperature < -50.0f || temperature > 150.0f) --- -### Module: mods/dual.c (Rendering Engine) +### Module: mods/display.c + dual.c + circle.c (Rendering) -#### Public API (2 functions) +#### Public API | Function | Purpose | Returns | |----------|---------|---------| -| `draw_combined_image(config)` | High-level: fetch data + render + upload | `void` | -| `render_display(config, data, device_name)` | Low-level: Cairo PNG generation | `int` success | +| `draw_display_image(config)` | Dispatch to dual or circle mode | `void` | +| `draw_dual_image(config)` | Render CPU+GPU simultaneously, upload | `void` | +| `draw_circle_image(config)` | Render alternating sensor slot, upload | `void` | -#### Internal Helpers (13+ functions) +#### Internal Helpers ```c calculate_scaling_params() // Compute inscribe factor, margins @@ -978,122 +953,95 @@ log_message(LOG_ERROR, "Failed to connect to API"); // Always **Steps:** -1. **Add field to Config struct** (`src/device/sys.h`) -2. **Add default value** (`src/device/sys.c` โ†’ `set_display_defaults()` or appropriate function) -3. **Add INI parser** (`src/device/usr.c` โ†’ handler function + entry in ConfigEntry array) +1. **Add field to Config struct** (`src/device/config.h`) +2. **Add default value** (`src/device/config.c` โ†’ appropriate `set_*_defaults()`) +3. **Add JSON parsing** (`src/device/config.c` โ†’ `load_*_from_json()` function) 4. **Update documentation** (`docs/config-guide.md`) -5. **Update example config** (`etc/coolerdash/config.ini`) +5. **Update example config** (`/etc/coolercontrol/plugins/coolerdash/config.json`) **Example 1: Adding Circle Mode Switch Interval (uint16_t with validation)** ```c -// 1. sys.h - Add field to Config struct +// 1. config.h - Add field to Config struct typedef struct { // ... uint16_t circle_switch_interval; // Circle mode sensor switch interval (1-60s) } Config; -// 2. sys.c - Set default value -void set_display_defaults(Config *config) { - // ... - config->circle_switch_interval = 5; // Default: 5 seconds +// 2. config.c - Set default value +static void set_display_defaults(Config *config) { + if (config->circle_switch_interval == 0) + config->circle_switch_interval = 5; } -// 3. usr.c - Add handler with validation -static int handle_circle_switch_interval(void *user, const char *section, - const char *name, const char *value) { - Config *config = (Config *)user; - if (strcmp(section, "display") == 0 && strcmp(name, "circle_switch_interval") == 0) { - long val = strtol(value, NULL, 10); - if (val >= 1 && val <= 60) { - config->circle_switch_interval = (uint16_t)val; - record_config_change(section, name, value); - } else { +// 3. config.c - Add JSON parsing +static void load_display_from_json(Config *config, json_t *display) { + json_t *val = json_object_get(display, "circle_switch_interval"); + if (json_is_integer(val)) { + long v = json_integer_value(val); + if (v >= 1 && v <= 60) + config->circle_switch_interval = (uint16_t)v; + else log_message(LOG_WARNING, "circle_switch_interval must be 1-60, using default: 5"); - } - return 1; } - return 0; } - -// Add to DisplayConfigEntry array -static const DisplayConfigEntry display_config_entries[] = { - // ... - {"circle_switch_interval", handle_circle_switch_interval}, -}; ``` **Example 2: Adding Content Scale Factor (float with validation)** ```c -// 1. sys.h - Add field to Config struct +// 1. config.h - Add field to Config struct typedef struct { // ... float display_content_scale_factor; // Content scale factor (0.5-1.0) } Config; -// 2. sys.c - Set default value -void set_display_defaults(Config *config) { +// 2. config.c - Set default value +static void set_display_defaults(Config *config) { // ... config->display_content_scale_factor = 0.98f; // Default: 98% (2% margin) } -// 3. usr.c - Add handler with validation -static int handle_content_scale_factor(void *user, const char *section, - const char *name, const char *value) { - Config *config = (Config *)user; - if (strcmp(section, "display") == 0 && strcmp(name, "content_scale_factor") == 0) { - float val = strtof(value, NULL); - if (val >= 0.5f && val <= 1.0f) { - config->display_content_scale_factor = val; - record_config_change(section, name, value); - } else { - log_message(LOG_WARNING, "content_scale_factor must be 0.5-1.0, using default: 0.98"); - } - return 1; +// 3. config.c - Add JSON parsing +static void load_display_from_json(Config *config, json_t *display) { + json_t *val = json_object_get(display, "content_scale_factor"); + if (json_is_real(val)) { + float f = (float)json_real_value(val); + if (f >= 0.5f && f <= 1.0f) + config->display_content_scale_factor = f; } - return 0; } - -// Add to DisplayConfigEntry array -static const DisplayConfigEntry display_config_entries[] = { - // ... - {"content_scale_factor", handle_content_scale_factor}, -}; ``` **Example 3: Adding New Color** ```c -// 1. sys.h +// 1. config.h typedef struct { // ... Color color_my_new_element; } Config; -// 2. sys.c -void set_color_defaults(Config *config) { +// 2. config.c - Set default value +static void set_color_defaults(Config *config) { // ... config->color_my_new_element = (Color){0, 255, 0}; // Green } -// 3. usr.c -static int get_color_config(Config *config, const char *section, - const char *name, const char *value) { - // ... - else if (strcmp(section, "color_my_element") == 0) { - parse_color_component(value, name, &config->color_my_new_element); - } +// 3. config.c - Add JSON parsing +static void load_colors_from_json(Config *config, json_t *colors) { + json_t *my_obj = json_object_get(colors, "my_new_element"); + if (json_is_object(my_obj)) + parse_color_from_json(my_obj, &config->color_my_new_element); } ``` **Configuration Best Practices:** -- Always provide sensible defaults -- Validate user input with clear error messages -- Use appropriate data types (uint16_t for small integers, float for decimals) -- Document acceptable ranges in both code comments and config.ini +- Always provide sensible defaults in `set_*_defaults()` +- Validate user input with clear error messages using `log_message(LOG_WARNING, ...)` +- Use appropriate data types (`uint16_t` for small integers, `float` for decimals) +- Document acceptable ranges in both code comments and `config.json` - Log warnings for invalid values and fallback to defaults -- Record configuration changes for debugging with `record_config_change()` --- @@ -1162,7 +1110,7 @@ systemctl status coolercontrold curl -u CCAdmin:coolAdmin -X POST http://localhost:11987/login # Check config password -grep daemon_password /etc/coolerdash/config.ini +grep daemon_password /etc/coolercontrol/plugins/coolerdash/config.json ``` --- @@ -1303,7 +1251,7 @@ coolerdash --verbose 2>&1 | grep -E "(Session|Temperature|Upload)" **MIT License** - See LICENSE file for full text. -**Copyright (c) 2025 damachine (christkue79@gmail.com)** +**Copyright (c) 2025 damachine (damachin3@proton.me)** --- @@ -1315,18 +1263,16 @@ coolerdash --verbose 2>&1 | grep -E "(Session|Temperature|Upload)" - **Cairo Graphics:** https://www.cairographics.org/manual/ - **libcurl:** https://curl.se/libcurl/c/ - **Jansson JSON:** https://jansson.readthedocs.io/ -- **inih Parser:** https://github.com/benhoyt/inih ### Project Files -- **Configuration Guide:** `/docs/config.md` -- **Supported Devices:** `/docs/devices.md` -- **Display Detection:** `/docs/display-shape-detection.md` -- **Makefile:** `/Makefile` -- **Example Config:** `/etc/coolerdash/config.ini` +- **Configuration Guide:** `docs/config-guide.md` +- **Supported Devices:** `docs/devices.md` +- **Display Detection:** `docs/display-detection.md` +- **Example Config:** `etc/coolercontrol/plugins/coolerdash/config.json` --- -**Document Version:** 1.0 -**Last Updated:** November 5, 2025 -**Maintained by:** damachine (christkue79@gmail.com) +**Document Version:** 2.x +**Last Updated:** 2026 +**Maintained by:** damachine (damachin3@proton.me) diff --git a/docs/devices.md b/docs/devices.md index d48f3e0..faf8339 100644 --- a/docs/devices.md +++ b/docs/devices.md @@ -13,10 +13,7 @@ | NZXT | Kraken 2023 | โœ… Working | @olivetti80 | 2025-09-12 | | NZXT | Kraken 2023 Elite | โš ๏ธ Partially | @Mondkeks | 2025-10-09 | | NZXT | Kraken Z63 | โœ… Working | @SSUPD-Beast | 2025-11-24 | -| ? | ? | ? | ? | ? | -| ? | ? | ? | ? | ? | -| ? | ? | ? | ? | ? | -| ? | ? | ? | ? | ? | +| NZXT | Kraken Plus 240 | โŒ Not working | @K-Michallik | 2026-02-23 | | ? | ? | ? | ? | ? | |------------------|--------------------------|---------------|-------------------------|------------| diff --git a/docs/display-detection.md b/docs/display-detection.md index f4b0eb1..1ecf751 100644 --- a/docs/display-detection.md +++ b/docs/display-detection.md @@ -7,30 +7,27 @@ The system automatically detects whether a display is **circular** (round) or ** ## Configuration Override -**New in v1.96:** Manual control via `config.ini` - -```ini -[display] -# Display shape override (auto, rectangular, circular) -# - auto: Auto-detection based on device database (default) -# - rectangular: Force inscribe_factor=1.0 (full width) -# - circular: Force inscribe_factor=0.7071 (inscribed circle) -shape = auto +**Manual control via `config.json`** + +```json +{ + "display": { + "shape": "auto" + } +} ``` +> Values: `"auto"` (default), `"rectangular"`, `"circular"` + ### Priority System 1. **`shape` config parameter** (highest priority - manual override) -2. **`--force-display-circular` CLI flag** (deprecated, kept for compatibility) -3. **Automatic detection** (default behavior) +2. **Automatic detection** (default behavior) **Examples:** ```bash -# Config file takes precedence -coolerdash # Uses shape from config.ini - -# CLI flag overrides auto-detection only (not config) -coolerdash --force-display-circular # Only if shape=auto in config +# Config file controls shape +coolerdash # Uses shape from config.json ``` ## Automatic Detection @@ -112,7 +109,7 @@ If circle radius = R: **Circular Displays:** ``` -inscribe_factor = 0.7071 (reduced safe area) - NOTE: The `inscribe_factor` is configurable via `display_inscribe_factor` in `config.ini`; default is 0.70710678 (0.0 = auto) +inscribe_factor = 0.7071 (reduced safe area) - NOTE: The `inscribe_factor` is configurable via `display_inscribe_factor` in `config.json`; default is 0.70710678 (0.0 = auto) safe_area_width = 240 ร— 0.7071 = ~170px safe_bar_width = 170 ร— 0.98 = ~167px margin = (240 - 170) / 2 = ~35px @@ -140,7 +137,7 @@ margin = (320 - 226) / 2 = ~47px ### Adding a Circular Display (Non-Kraken) -Edit `src/coolercontrol.c`, function `is_circular_display_device()`: +Edit `src/srv/cc_conf.c`, function `is_circular_display_device()`: ```c const char *circular_devices[] = { @@ -219,7 +216,7 @@ The system logs the detection: ### Function: `is_circular_display_device()` -**Location**: `src/coolercontrol.c` +**Location**: `src/srv/cc_conf.c` **Signature**: ```c @@ -244,7 +241,7 @@ int is_circular_display_device(const char *device_name, int screen_width, int sc ### C Functions ```c -// In coolercontrol.h/c +// In cc_conf.h/c int is_circular_display_device(const char *device_name, int screen_width, int screen_height); // In display.c @@ -254,11 +251,7 @@ static void calculate_scaling_params( const char *device_name ); -int render_display( - const struct Config *config, - const monitor_sensor_data_t *data, - const char *device_name -); +void draw_display_image(const struct Config *config); ``` ## Testing @@ -301,7 +294,7 @@ Expected output for **NZXT Kraken Z (320ร—320)**: **Cause**: Device not detected as circular **Solution Options**: -1. **Quick fix (recommended)**: Set `shape=circular` in `/etc/coolerdash/config.ini` +1. **Quick fix (recommended)**: Set `shape` to `"circular"` in `config.json` 2. For NZXT Kraken: Verify resolution is >240ร—240 3. For other devices: Add device name to database in `cc_conf.c` @@ -310,7 +303,7 @@ Expected output for **NZXT Kraken Z (320ร—320)**: **Cause**: Incorrectly detected as circular **Solution Options**: -1. **Quick fix (recommended)**: Set `shape=rectangular` in `/etc/coolerdash/config.ini` +1. **Quick fix (recommended)**: Set `shape` to `"rectangular"` in `config.json` 2. For NZXT Kraken: Verify resolution is โ‰ค240ร—240 3. For other devices: Ensure not in circular device database @@ -318,18 +311,16 @@ Expected output for **NZXT Kraken Z (320ร—320)**: **Cause**: Not in database and not NZXT Kraken -**Solution**: This is intentional (safe default). Use `shape=circular` in config if needed. +**Solution**: This is intentional (safe default). Set `shape` to `"circular"` in `config.json` if needed. ### Testing Shape Override ```bash -# Test rectangular layout -echo "shape=rectangular" >> /etc/coolerdash/config.ini -systemctl restart coolerdash.service +# Test rectangular layout - set in config.json: "shape": "rectangular" +sudo systemctl restart coolerdash.service -# Test circular layout -echo "shape=circular" >> /etc/coolerdash/config.ini -systemctl restart coolerdash.service +# Test circular layout - set in config.json: "shape": "circular" +sudo systemctl restart coolerdash.service # Check logs for inscribe factor journalctl -u coolerdash.service -f | grep "inscribe" @@ -345,7 +336,7 @@ Expected output with manual override: ### Problem: Display Detected Incorrectly **Solution for Circular display treated as rectangular:** -- Add device name to database in `coolercontrol.c` +- Add device name to database in `cc_conf.c` **Solution for Rectangular display treated as circular:** 1. Check if device name is incorrectly in `circular_devices[]` diff --git a/docs/display-modes.md b/docs/display-modes.md index 1e971d1..3c3eda9 100644 --- a/docs/display-modes.md +++ b/docs/display-modes.md @@ -23,11 +23,11 @@ CoolerDash supports two distinct display modes for rendering temperature informa The mode is selected through a three-tier configuration system: -1. **System Default** (`src/device/sys.c`): `display_mode = "dual"` -2. **User Configuration** (`etc/coolerdash/config.ini`): `[display] mode=dual|circle` +1. **System Default** (`src/device/config.c`): `display_mode = "dual"` +2. **User Configuration** (`/etc/coolercontrol/plugins/coolerdash/config.json`): `"mode": "dual"|"circle"` 3. **CLI Override** (`src/main.c`): `--dual` or `--circle` flags -Priority: **CLI > INI > Default** +Priority: **CLI > JSON > Default** --- @@ -37,6 +37,8 @@ Priority: **CLI > INI > Default** ``` src/mods/ +โ”œโ”€โ”€ display.c # Mode dispatcher +โ”œโ”€โ”€ display.h # Dispatcher API โ”œโ”€โ”€ dual.c # Dual mode implementation โ”œโ”€โ”€ dual.h # Dual mode API โ”œโ”€โ”€ circle.c # Circle mode implementation @@ -45,10 +47,10 @@ src/mods/ ### Mode Dispatcher -The mode dispatcher is located in `src/mods/dual.c`: +The mode dispatcher is located in `src/mods/display.c`: ```c -void draw_combined_image(const struct Config *config) +void draw_display_image(const struct Config *config) { if (strcmp(config->display_mode, "circle") == 0) { draw_circle_image(config); @@ -183,7 +185,7 @@ static time_t last_switch_time = 0; #### 3. Configuration-Based Timing -The sensor switch interval is **configurable** via `config.ini`: +The sensor switch interval is **configurable** via `config.json`: ```c // No longer hardcoded - uses Config parameter @@ -199,12 +201,14 @@ void update_sensor_mode(const struct Config *config) } ``` -**Configuration:** -```ini -[display] -mode=circle -circle_switch_interval=5 # 1-60 seconds, default: 5 -``` +**Configuration (`config.json`):** +```json +{ + "display": { + "mode": "circle", + "circle_switch_interval": 5 + } +} **Use Cases:** - **Fast (1-3s):** Quick sensor overview @@ -281,14 +285,14 @@ This ensures visual balance by treating "45ยฐ" as a single unit rather than cent ### Timing Implementation -The sensor switching interval is **configurable** via `config.ini` (1-60 seconds, default: 5): +The sensor switching interval is **configurable** via `config.json` (1-60 seconds, default: 5): ```c void update_sensor_mode(const struct Config *config) { time_t current_time = time(NULL); - // Use configurable interval from config.ini + // Use configurable interval from config.json if (difftime(current_time, last_switch_time) >= config->circle_switch_interval) { current_sensor = (current_sensor == SENSOR_CPU) ? SENSOR_GPU : SENSOR_CPU; last_switch_time = current_time; @@ -296,12 +300,14 @@ void update_sensor_mode(const struct Config *config) } ``` -**Configuration:** -```ini -[display] -mode=circle -circle_switch_interval=5 # 1-60 seconds, default: 5 -``` +**Configuration (`config.json`):** +```json +{ + "display": { + "mode": "circle", + "circle_switch_interval": 5 + } +} **Note**: For sub-second precision, `nanosleep()` or `clock_gettime()` could be used, but the current implementation provides sufficient accuracy for display purposes. @@ -311,39 +317,33 @@ circle_switch_interval=5 # 1-60 seconds, default: 5 ### Config Structure Extension -The `Config` structure in `src/device/sys.h` includes: +The `Config` structure in `src/device/config.h` includes: ```c char display_mode[16]; // "dual" or "circle" ``` -### System Defaults (`src/device/sys.c`) +### System Defaults (`src/device/config.c`) ```c -void set_display_defaults(struct Config *config) +static void set_display_defaults(struct Config *config) { // ... other defaults ... - cc_safe_strcpy(config->display_mode, "dual", sizeof(config->display_mode)); + cc_safe_strcpy(config->display_mode, sizeof(config->display_mode), "dual"); } ``` -### INI Parsing (`src/device/usr.c`) +### JSON Parsing (`src/device/config.c`) ```c -static int handle_display_mode(void *user, const char *section, - const char *name, const char *value) +static void load_display_from_json(Config *config, json_t *display) { - struct Config *config = (struct Config *)user; - - if (strcmp(section, "display") == 0 && strcmp(name, "mode") == 0) { - if (strcmp(value, "dual") == 0 || strcmp(value, "circle") == 0) { - cc_safe_strcpy(config->display_mode, value, - sizeof(config->display_mode)); - return 1; - } + json_t *val = json_object_get(display, "mode"); + if (json_is_string(val)) { + const char *mode = json_string_value(val); + if (strcmp(mode, "dual") == 0 || strcmp(mode, "circle") == 0) + SAFE_STRCPY(config->display_mode, mode); } - return 0; } -``` ### CLI Override (`src/main.c`) @@ -379,14 +379,14 @@ int main(int argc, char *argv[]) ### 1. Main Loop (`src/main.c`) ```c while (1) { - draw_combined_image(&config); // Mode dispatcher + draw_display_image(&config); // Mode dispatcher sleep(update_interval); } ``` -### 2. Mode Dispatcher (`src/mods/dual.c`) +### 2. Mode Dispatcher (`src/mods/display.c`) ```c -void draw_combined_image(const struct Config *config) +void draw_display_image(const struct Config *config) { if (strcmp(config->display_mode, "circle") == 0) { draw_circle_image(config); @@ -457,26 +457,19 @@ int is_circular = is_circular_display_device(device_name, width, height); ### Display Shape Override (New in v1.96) -**Recommended Method:** Manual configuration override in `config.ini`: -```ini -[display] -# Display shape override (auto, rectangular, circular) -# - auto: Auto-detection based on device database (default) -# - rectangular: Force inscribe_factor=1.0 (full width) -# - circular: Force inscribe_factor=0.7071 (inscribed circle). Note: The value is configurable via `display_inscribe_factor` in `config.ini` (default: 0.70710678) โ€” 0.0 = auto -shape = auto -``` - -**Legacy Method (Deprecated):** CLI flag for backwards compatibility: -```ini -[display] -force_circular = true +**Recommended Method:** Manual configuration override in `config.json`: +```json +{ + "display": { + "shape": "auto" + } +} ``` +> Values: `"auto"` (default), `"rectangular"`, `"circular"` โ€” `"circular"` inscribe factor is configurable via `display_inscribe_factor` (default: 0.70710678; 0.0 = auto). **Priority System:** 1. `shape` config parameter (highest - manual override) -2. `force_display_circular` flag (legacy compatibility) -3. Automatic device detection (default) +2. Automatic device detection (default) **Use cases:** - Testing circular layout on rectangular displays @@ -517,7 +510,7 @@ Create `src/mods/newmode.c` and `src/mods/newmode.h`: #ifndef NEWMODE_H #define NEWMODE_H -#include "../device/sys.h" +#include "../device/config.h" void draw_newmode_image(const struct Config *config); @@ -577,7 +570,7 @@ In `src/mods/dual.c`, add your mode: ```c #include "newmode.h" -void draw_combined_image(const struct Config *config) +void draw_display_image(const struct Config *config) { if (strcmp(config->display_mode, "newmode") == 0) { draw_newmode_image(config); @@ -598,14 +591,13 @@ HEADERS = ... src/mods/newmode.h #### 5. Update Configuration -Add validation in `src/device/usr.c`: +Add validation in `src/device/config.c`: ```c -if (strcmp(value, "dual") == 0 || - strcmp(value, "circle") == 0 || - strcmp(value, "newmode") == 0) { - cc_safe_strcpy(config->display_mode, value, sizeof(config->display_mode)); - return 1; +if (strcmp(mode, "dual") == 0 || + strcmp(mode, "circle") == 0 || + strcmp(mode, "newmode") == 0) { + SAFE_STRCPY(config->display_mode, mode); } ``` @@ -626,7 +618,7 @@ printf(" --newmode Use new display mode\n"); #### 7. Update Documentation - `README.md`: Add mode description -- `etc/coolerdash/config.ini`: Add example +- `/etc/coolercontrol/plugins/coolerdash/config.json`: Add example - `docs/display-modes.md`: Add technical details --- @@ -754,7 +746,7 @@ Current implementation uses `time()` for 5s intervals: Compile with `-DDEBUG`: ```bash -gcc -g -O0 -DDEBUG src/*.c -o coolerdash -lcurl -lcairo -lm -ljansson -linih +gcc -g -O0 -DDEBUG src/*.c -o coolerdash -lcurl -lcairo -lm -ljansson ``` ### 2. Test PNG Output diff --git a/docs/plugin-integration.md b/docs/plugin-integration.md index 3f17060..3478a5b 100644 --- a/docs/plugin-integration.md +++ b/docs/plugin-integration.md @@ -4,7 +4,7 @@ CoolerDash is now fully integrated as a CoolerControl plugin with enhanced UI support. -## New Features in 2.0.5 +## New Features in 2.2.x ### 1. Theme-Adaptive UI @@ -48,7 +48,7 @@ Consistent iconography using CoolerControl's icon library: The `manifest.toml` now includes: ```toml -version = "2.0.5" # Displayed in plugin list +version = "2.2.x" # Displayed in plugin list url = "https://github.com/damachine/coolerdash" # Link to project homepage ``` @@ -65,7 +65,7 @@ These fields are displayed on the CoolerControl plugin page, helping users: - โŒ Custom CSS only (no Tailwind support) - โŒ Toast notifications (not standard in CC) -### After (2.0.5) +### After (2.2.x) - โœ… Theme-adaptive colors using CSS variables - โœ… Tailwind CSS for consistent styling diff --git a/docs/plugin-ui-theming.md b/docs/plugin-ui-theming.md index 2df28bd..5e6fca6 100644 --- a/docs/plugin-ui-theming.md +++ b/docs/plugin-ui-theming.md @@ -178,7 +178,7 @@ See [index.html](../etc/coolercontrol/plugins/coolerdash/index.html) for a compl Add version and URL to your `manifest.toml`: ```toml -version = "2.0.5" +version = "2.2.x" url = "https://github.com/damachine/coolerdash" ``` @@ -186,5 +186,5 @@ These will be displayed on the plugin page in CoolerControl's UI. ## Changelog -- **2.0.5** - Added theme color support and Tailwind CSS integration +- **2.2.x** - Added theme color support and Tailwind CSS integration - **2.0.4** - Initial plugin UI implementation diff --git a/etc/coolercontrol/plugins/coolerdash/ui/index.html b/etc/coolercontrol/plugins/coolerdash/ui/index.html index 6efff9b..b1cdc73 100644 --- a/etc/coolercontrol/plugins/coolerdash/ui/index.html +++ b/etc/coolercontrol/plugins/coolerdash/ui/index.html @@ -1953,16 +1953,8 @@

System Environment

} async function loadDefaultConfig() { - try { - var response = await fetch('config.json'); - if (!response.ok) throw new Error('HTTP ' + response.status); - DEFAULT_CONFIG = await response.json(); - return DEFAULT_CONFIG; - } catch (error) { - console.error("Failed to load config.json:", error); - DEFAULT_CONFIG = FACTORY_DEFAULTS; - return DEFAULT_CONFIG; - } + DEFAULT_CONFIG = FACTORY_DEFAULTS; + return DEFAULT_CONFIG; } // ===== BUILD CONFIG FROM FORM =====