Skip to content

feat(metaballs): Make speed and radius configurable in metaballs mode - #788

Draft
Solmath wants to merge 11 commits into
VIPnytt:mainfrom
Solmath:feature/metaballs-configuration-params
Draft

feat(metaballs): Make speed and radius configurable in metaballs mode#788
Solmath wants to merge 11 commits into
VIPnytt:mainfrom
Solmath:feature/metaballs-configuration-params

Conversation

@Solmath

@Solmath Solmath commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

This adds parameters to configure speed and size of the balls from the frontend.

Key changes

  • Exposes speed and radius parameters in the firmware
  • Adds sidebar components for metaballs in the webapp

Impact

  • Users can now manipulate the speed of the balls with a slider.
    • Balls will use the new value only after the next bounce from a wall.
    • Increased the default speed and reduced the multiplier to get a more uniform movement. (Multiplier could be made configurable in a follow up.
  • Users can now select the size of the balls with a dropdown
    • I initially added a slider, but not all values make sense (that's also why the backend accepts numerical values)

ToDo

Add config parameters for multiplier, feathering and number of balls.

…radius

- Introduced methods to set and retrieve speed and radius factors from non-volatile storage.
- Updated the `configure`, `setSpeed`, `setRadius`, and `transmit` methods to handle new parameters.
- Adjusted calculations for speed and radius based on user-defined factors.
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Approval pending

CodeRabbit has no unresolved comments, but it skipped the latest review.

Use the checkbox below to review the latest commit. CodeRabbit will approve the changes if it finds no blocking issues.

  • 🔍 Trigger review

Summary by CodeRabbit

  • New Features
    • Added adjustable speed and radius controls for Metaballs mode.
    • Settings are saved and synchronized between the device and web interface.
    • Added multiple radius options and a dedicated control sidebar.
    • Improved visual rendering with configurable feathering and refreshed initialization behavior.

Walkthrough

Metaballs now supports configurable speed and radius settings. Firmware persists and publishes these values, while the web application provides controls and applies incoming updates.

Changes

Metaballs configuration

Layer / File(s) Summary
Metaballs rendering runtime
firmware/include/modes/MetaballsMode.h, firmware/src/modes/MetaballsMode.cpp
Metaballs uses derived speed and radius values, configurable feathering, updated brightness calculations, display clearing, and one fewer ball.
Firmware configuration and synchronization
firmware/src/modes/MetaballsMode.cpp
Firmware restores settings from NVS, clamps and persists updates, recalculates derived values, publishes configuration, and processes received payloads.
Web control integration
webapp/src/modes/Metaballs.tsx, webapp/src/services/Modes.tsx
The Metaballs sidebar provides speed and radius controls, sends updates over WebSocket, applies received values, and renders for the selected mode.

Sequence Diagram(s)

sequenceDiagram
  participant Sidebar
  participant WebSocket
  participant MetaballsMode
  participant NVS
  Sidebar->>WebSocket: send speed or radius setting
  WebSocket->>MetaballsMode: onReceive(payload)
  MetaballsMode->>NVS: persist validated setting
  MetaballsMode->>WebSocket: publish active configuration
  WebSocket->>Sidebar: apply received speed and radius
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main change: configurable speed and radius for Metaballs mode.
Description check ✅ Passed The description includes the required summary, key changes, and impact sections, with relevant implementation details and future work.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added frontend Web app related firmware C++ related labels Aug 21, 2026
@Solmath
Solmath marked this pull request as ready for review August 21, 2026 15:01
@Solmath
Solmath requested a review from JanPetterMG as a code owner August 21, 2026 15:01
Comment thread firmware/src/modes/MetaballsMode.cpp Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b91b150c-61ad-4f13-9fe6-06673e492c68

📥 Commits

Reviewing files that changed from the base of the PR and between e190e49 and afd2812.

📒 Files selected for processing (4)
  • firmware/include/modes/MetaballsMode.h
  • firmware/src/modes/MetaballsMode.cpp
  • webapp/src/modes/Metaballs.tsx
  • webapp/src/services/Modes.tsx

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Review details
⏰ Context from checks skipped due to timeout. (84)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32-c6-devkitm-1)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32dev)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32-c5-devkitc-1)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32-c3-devkitm-1)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32-c6-devkitm-1)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32-c3-devkitm-1)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32-s3-devkitc-1)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32-c5-devkitc-1)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32-s3-devkitc-1)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32dev)
  • GitHub Check: Default (seeed_xiao_esp32s3)
  • GitHub Check: Minimal (seeed_xiao_esp32c6)
  • GitHub Check: Minimal (seeed_xiao_esp32s3)
  • GitHub Check: Minimal (lolin_d32)
  • GitHub Check: Default (lolin_d32)
  • GitHub Check: Minimal (esp32-c6-devkitm-1)
  • GitHub Check: Minimal (lolin_s3_mini)
  • GitHub Check: Minimal (wemos_d1_mini32)
  • GitHub Check: Minimal (esp32-c5-devkitc-1)
  • GitHub Check: Default (wemos_d1_mini32)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s3_n4r2)
  • GitHub Check: Minimal (lolin_d32_pro)
  • GitHub Check: Default (lolin_s3_mini)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s2)
  • GitHub Check: Default (seeed_xiao_esp32c3)
  • GitHub Check: Minimal (esp32-s3-devkitc-1)
  • GitHub Check: Default (esp32dev)
  • GitHub Check: Default (adafruit_qtpy_esp32s3_n4r2)
  • GitHub Check: Minimal (seeed_xiao_esp32c3)
  • GitHub Check: Default (seeed_xiao_esp32c6)
  • GitHub Check: Default (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Default (esp32-c6-devkitm-1)
  • GitHub Check: Default (lolin_d32_pro)
  • GitHub Check: Minimal (esp32-c3-devkitm-1)
  • GitHub Check: Minimal (esp32dev)
  • GitHub Check: Default (esp32-c3-devkitm-1)
  • GitHub Check: Default (esp32-s3-devkitc-1)
  • GitHub Check: Default (adafruit_qtpy_esp32s2)
  • GitHub Check: Default (esp32-c5-devkitc-1)
  • GitHub Check: Typical (seeed_xiao_esp32s3)
  • GitHub Check: Extensive (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Typical (esp32-s3-devkitc-1)
  • GitHub Check: Typical (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Extensive (esp32-s3-devkitc-1)
  • GitHub Check: Extensive (seeed_xiao_esp32s3)
  • GitHub Check: Minimal (lolin_d32_pro)
  • GitHub Check: Default (seeed_xiao_esp32c6)
  • GitHub Check: Default (lolin_s3_mini)
  • GitHub Check: Default (lolin_d32_pro)
  • GitHub Check: Default (wemos_d1_mini32)
  • GitHub Check: Default (lolin_d32)
  • GitHub Check: Minimal (wemos_d1_mini32)
  • GitHub Check: Default (seeed_xiao_esp32c3)
  • GitHub Check: Minimal (esp32-c5-devkitc-1)
  • GitHub Check: Default (esp32-c6-devkitm-1)
  • GitHub Check: Default (esp32-s3-devkitc-1)
  • GitHub Check: Default (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Default (esp32-c3-devkitm-1)
  • GitHub Check: Minimal (seeed_xiao_esp32c3)
  • GitHub Check: Default (esp32-c5-devkitc-1)
  • GitHub Check: Default (adafruit_qtpy_esp32s3_n4r2)
  • GitHub Check: Minimal (esp32-c6-devkitm-1)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s3_n4r2)
  • GitHub Check: Minimal (seeed_xiao_esp32c6)
  • GitHub Check: Minimal (esp32-s3-devkitc-1)
  • GitHub Check: Default (seeed_xiao_esp32s3)
  • GitHub Check: Default (adafruit_qtpy_esp32s2)
  • GitHub Check: Default (esp32dev)
  • GitHub Check: Minimal (esp32-c3-devkitm-1)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s2)
  • GitHub Check: Minimal (lolin_d32)
  • GitHub Check: Minimal (seeed_xiao_esp32s3)
  • GitHub Check: Minimal (lolin_s3_mini)
  • GitHub Check: Minimal (esp32dev)
  • GitHub Check: Typical (seeed_xiao_esp32s3)
  • GitHub Check: Extensive (esp32-s3-devkitc-1)
  • GitHub Check: Extensive (seeed_xiao_esp32s3)
  • GitHub Check: Typical (esp32-s3-devkitc-1)
  • GitHub Check: Typical (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Extensive (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: ESPHome (2025.7.0)
  • GitHub Check: ESPHome (latest)
🔇 Additional comments (1)
webapp/src/services/Modes.tsx (1)

81-85: LGTM!

Also applies to: 337-341

Comment thread firmware/include/modes/MetaballsMode.h Outdated
Comment thread webapp/src/modes/Metaballs.tsx
Comment thread webapp/src/modes/Metaballs.tsx
@Solmath
Solmath marked this pull request as draft August 24, 2026 16:32
@JanPetterMG

Copy link
Copy Markdown
Collaborator

Thinking of taking a closer look at this during the weekend. Having controls in the web UI would be very much appreciated.

@Solmath

Solmath commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

I just pushed my latest changes that try to simplify the initialization of the contributions array and add support to change the number of balls during runtime.

I should probably split this into multiple PRs, because it really touches on different topics, will try to do that over the weekend.

By the way, I vibe coded a little playground app to experiment with the parameters without the need to flash the firmware on every change: https://gist.github.com/Solmath/29248d049256089fa09f7db272c2ba90

Should be working without any dependencies.

@JanPetterMG JanPetterMG added this to the v2.6.0 milestone Aug 30, 2026
@JanPetterMG

Copy link
Copy Markdown
Collaborator

Had some fun playing around with the new settings and seeing how everything interacts. The “these go to eleven” easter egg in the web UI made me smile.

There's some tweaking and polishing to do, but overall this is a very welcome improvement. Looking forward to seeing the finished version. 👍🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

firmware C++ related frontend Web app related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants