Skip to content

Fix: Correctly determine number of PID profiles#544

Closed
nerdCopter wants to merge 1 commit intoemuflight:masterfrom
nerdCopter:20251019_fix_copy_profile
Closed

Fix: Correctly determine number of PID profiles#544
nerdCopter wants to merge 1 commit intoemuflight:masterfrom
nerdCopter:20251019_fix_copy_profile

Conversation

@nerdCopter
Copy link
Copy Markdown
Member

@nerdCopter nerdCopter commented Feb 8, 2026

The logic for determining the number of PID profiles was flawed, preventing users from copying to profile 3.

This commit corrects the logic to trust the numProfiles value from the firmware when available (API version >= 1.20.0), and falls back to a default of 3 for older versions. This ensures the correct number of profiles is displayed and the copy functionality works as expected.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed PID tuning profile configuration to properly apply profile count settings when using newer API versions. Previously, an unnecessary restriction prevented correct profile settings from being applied in certain scenarios. The updated logic now enables proper profile handling with improved compatibility.

The logic for determining the number of PID profiles was flawed,
preventing users from copying to profile 3.

This commit corrects the logic to trust the `numProfiles` value from the
firmware when available (API version >= 1.20.0), and falls back to a
default of 3 for older versions. This ensures the correct number of
profiles is displayed and the copy functionality works as expected.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 8, 2026

📝 Walkthrough

Walkthrough

Modified the conditional logic in loadProfilesList to apply CONFIG.numProfiles whenever API version is 1.20.0 or higher, removing the additional guard requiring CONFIG.numProfiles to equal 2. This broadens when the profile count configuration is applied based on API compatibility.

Changes

Cohort / File(s) Summary
Profile Configuration Logic
src/js/tabs/pid_tuning.js
Relaxed guard condition in loadProfilesList to set numberOfProfiles to CONFIG.numProfiles for any API version >= 1.20.0, previously required CONFIG.numProfiles === 2.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately summarizes the main change: fixing PID profile count determination logic to correctly use firmware-provided values for API >= 1.20.0.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/js/tabs/pid_tuning.js`:
- Around line 1712-1714: The assignment to numberOfProfiles uses
CONFIG.numProfiles directly when semver.gte(CONFIG.apiVersion, "1.20.0"), which
can be undefined/0/NaN and will cause the profile selector loop
(numberOfProfiles) to produce zero options; change the assignment in that branch
to validate and fall back to a safe default (e.g., DEFAULT_NUM_PROFILES or a
constant) by coalescing only valid positive integers—e.g., set numberOfProfiles
= (Number.isFinite(Number(CONFIG.numProfiles)) && Number(CONFIG.numProfiles) >
0) ? Number(CONFIG.numProfiles) : DEFAULT_NUM_PROFILES—so semver.gte(...),
CONFIG.numProfiles, numberOfProfiles and the profile-generation loop are
protected.

Comment thread src/js/tabs/pid_tuning.js
Comment on lines +1712 to 1714
if (semver.gte(CONFIG.apiVersion, "1.20.0")) {
numberOfProfiles = CONFIG.numProfiles;
}
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Feb 8, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Guard against falsy CONFIG.numProfiles.

If CONFIG.numProfiles is undefined, 0, or NaN (e.g., firmware returns an unexpected value), numberOfProfiles becomes falsy and the loop on line 1717 produces zero options, breaking the profile selector entirely. Consider falling back to the default.

🛡️ Proposed fix
             if (semver.gte(CONFIG.apiVersion, "1.20.0")) {
-                numberOfProfiles = CONFIG.numProfiles;
+                numberOfProfiles = CONFIG.numProfiles || 3;
             }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (semver.gte(CONFIG.apiVersion, "1.20.0")) {
numberOfProfiles = CONFIG.numProfiles;
}
if (semver.gte(CONFIG.apiVersion, "1.20.0")) {
numberOfProfiles = CONFIG.numProfiles || 3;
}
🤖 Prompt for AI Agents
In `@src/js/tabs/pid_tuning.js` around lines 1712 - 1714, The assignment to
numberOfProfiles uses CONFIG.numProfiles directly when
semver.gte(CONFIG.apiVersion, "1.20.0"), which can be undefined/0/NaN and will
cause the profile selector loop (numberOfProfiles) to produce zero options;
change the assignment in that branch to validate and fall back to a safe default
(e.g., DEFAULT_NUM_PROFILES or a constant) by coalescing only valid positive
integers—e.g., set numberOfProfiles =
(Number.isFinite(Number(CONFIG.numProfiles)) && Number(CONFIG.numProfiles) > 0)
? Number(CONFIG.numProfiles) : DEFAULT_NUM_PROFILES—so semver.gte(...),
CONFIG.numProfiles, numberOfProfiles and the profile-generation loop are
protected.

Copy link
Copy Markdown
Member Author

@nerdCopter nerdCopter Mar 9, 2026

Choose a reason for hiding this comment

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

@coderabbitai, what is a better way to do this overall? Emuflight is a fork of Betaflight around version 3.8.7 . Emuflight does not have any older semver than 1.20.0, in fact emuflight's first semver is 1.40.0 so essentially the firmware only has 3 profiles during it's lifetime of releases. recommend proper code for the code in this area/span for the goals.

the 1.20.0 is simply for old compatibility.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@nerdCopter, given that Emuflight's minimum API version is always ≥ 1.40.0, the semver.gte(CONFIG.apiVersion, "1.20.0") check is entirely dead code — that branch will always be taken. The simplest and most correct approach is to remove the version guard entirely and just read CONFIG.numProfiles directly, with a safe fallback for any unexpected firmware value:

function loadProfilesList() {
    var numberOfProfiles = CONFIG.numProfiles || 3;

    var profileElements = [];
    for (var i = 0; i < numberOfProfiles; i++) {
        profileElements.push(i18n.getMessage("pidTuningProfileOption", [(i + 1)]));
    }
    return profileElements;
}

Why this is better:

  • Removes dead code: The semver.gte(CONFIG.apiVersion, "1.20.0") check is never false in Emuflight, so it just adds noise.
  • Uses firmware truth: CONFIG.numProfiles is the authoritative source — if a future firmware version ever changes it, this handles it automatically.
  • Safe fallback: || 3 guards against undefined, 0, or NaN from an unexpected firmware response, keeping the profile selector functional.

If you prefer slightly more explicit validation (ruling out negative numbers too):

var numberOfProfiles = (CONFIG.numProfiles > 0) ? CONFIG.numProfiles : 3;

Both are equivalent for practical purposes since the firmware will only ever return a positive integer here.


✏️ Learnings added
Learnt from: nerdCopter
Repo: emuflight/EmuConfigurator PR: 544
File: src/js/tabs/pid_tuning.js:1712-1714
Timestamp: 2026-03-09T14:03:37.978Z
Learning: Emuflight is a fork of Betaflight ~3.8.7. Emuflight's minimum API version is 1.40.0 — API versions below 1.40.0 (including 1.20.0) are never present in Emuflight firmware. Legacy semver checks like `semver.gte(CONFIG.apiVersion, "1.20.0")` in `src/js/tabs/pid_tuning.js` are dead code in Emuflight's context. Emuflight always has 3 PID profiles in its firmware lifetime.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@nerdCopter
Copy link
Copy Markdown
Member Author

Closing, this was a firmware bug fixed in emuflight/EmuFlight#1104

@nerdCopter nerdCopter closed this Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant