Skip to content

[RF] Fix CC1101 initialization on boot with saved RF config#2269

Merged
1technophile merged 1 commit intodevelopmentfrom
claude/issue-2264-20260106-1134
Jan 6, 2026
Merged

[RF] Fix CC1101 initialization on boot with saved RF config#2269
1technophile merged 1 commit intodevelopmentfrom
claude/issue-2264-20260106-1134

Conversation

@1technophile
Copy link
Owner

Description:

When a saved RF configuration exists in NVS, loadFromStorage() was loading the config but not calling iRFReceiver.enable(), which meant initCC1101() was never invoked during boot. This caused the CC1101 to not receive signals until the user manually toggled the RF receiver via the WebUI.

This fix adds a reinitReceiver parameter to loadFromStorage() that controls whether to disable/enable the receiver after loading config. By default it's true (for boot-time initialization), but loadFromMessage() passes false to avoid double initialization when loading config from MQTT messages.

Fixes #2264

Co-authored-by: Florian 1technophile@users.noreply.github.com
Co-authored-by: Odyno odyno@users.noreply.github.com

🤖 Generated with Claude Code

Checklist:

  • The pull request is done against the latest development branch
  • Only one feature/fix was added per PR and the code change compiles without warnings
  • I accept the DCO.

When a saved RF configuration exists in NVS, loadFromStorage() was loading
the config but not calling iRFReceiver.enable(), which meant initCC1101()
was never invoked during boot. This caused the CC1101 to not receive signals
until the user manually toggled the RF receiver via the WebUI.

This fix adds a reinitReceiver parameter to loadFromStorage() that controls
whether to disable/enable the receiver after loading config. By default it's
true (for boot-time initialization), but loadFromMessage() passes false to
avoid double initialization when loading config from MQTT messages.

Fixes #2264

Co-authored-by: Florian <1technophile@users.noreply.github.com>
Co-authored-by: Odyno <odyno@users.noreply.github.com>

🤖 Generated with [Claude Code](https://claude.ai/code)
@1technophile 1technophile merged commit e01b226 into development Jan 6, 2026
161 checks passed
@1technophile 1technophile deleted the claude/issue-2264-20260106-1134 branch January 6, 2026 11:47
@claude
Copy link

claude bot commented Jan 6, 2026

PR Review: [RF] Fix CC1101 initialization on boot with saved RF config

Summary

This PR fixes issue #2264 where the CC1101 RF module wasn't properly initialized on boot when a saved RF configuration existed in NVS. The root cause was that loadFromStorage() loaded the config but never called iRFReceiver.enable() to initialize the hardware.

Code Quality ✅

Good aspects:

  • Clean solution with minimal changes (15 additions, 7 deletions)
  • Well-documented parameter with clear docstring updates in both .cpp and .h files
  • Uses a sensible default (reinitReceiver = true) that ensures backwards compatibility
  • The fix correctly addresses the root cause identified in the issue

Design choice:
The approach of adding a reinitReceiver parameter with a default of true is appropriate. This ensures:

  1. Boot-time initialization (setupCommonRF() at main/commonRF.cpp:92) gets proper hardware initialization
  2. MQTT message handling (loadFromMessage()) avoids double initialization since it already calls disable()/enable() after fromJson()

Correctness Analysis ✅

The logic is sound:

  1. Boot path (setupCommonRFloadFromStorage()):

    • reinitReceiver defaults to true
    • Receiver is disabled then enabled, triggering initCC1101()
  2. MQTT message path (loadFromMessageloadFromStorage(false)):

    • Passes false to avoid double initialization
    • loadFromMessage() already calls disable()/enable() at lines 207-208
  3. Non-ESP32 platforms: The receiver initialization now happens unconditionally (outside the #ifdef ESP32 block), which is actually an improvement - previously non-ESP32 platforms only called enable() but never disable() first, and now they consistently get the disable/enable cycle when reinitReceiver is true.

Potential Concerns ⚠️

  1. Early return paths in ESP32 block: When deserialization fails (line 153) or config is null (line 157), the function returns early before the reinitReceiver block. This means if there's a corrupted config in NVS, the receiver won't be initialized at boot.

    Suggestion: Consider whether the receiver should still be initialized in these error cases:

    if (error) {
      Log.error(F("RF Config deserialization failed: %s, buffer capacity: %u" CR), error.c_str(), jsonBuffer.capacity());
      // Still initialize receiver with defaults on error?
      if (reinitReceiver) {
        iRFReceiver.disable();
        iRFReceiver.enable();
      }
      return;
    }
  2. Order of operations: Calling disable() before enable() is good practice for ensuring clean state. The current implementation correctly does this.

Performance ✅

No performance concerns - the disable/enable cycle only happens once at boot or on explicit config reload.

Security ✅

No security implications in this change.

Test Coverage 📝

The PR description mentions the fix was validated against the specific scenario in #2264 (boot with saved config). Manual testing appears to have confirmed the CC1101 now receives signals after boot without requiring WebUI toggle.

Recommendation: If the project has unit tests for RFConfiguration, consider adding test cases for:

  • loadFromStorage(true) - verify receiver is re-initialized
  • loadFromStorage(false) - verify receiver is not touched
  • Error paths (deserialization failure, null config)

Overall Assessment ✅

Approve - This is a well-crafted fix that addresses the reported issue with minimal, targeted changes. The code is clean, well-documented, and follows the project's existing patterns.

The one minor suggestion above (handling error paths) is optional and can be addressed in a follow-up if desired.


🤖 Review generated with Claude Code

Odyno added a commit to Odyno/OpenMQTTGateway that referenced this pull request Jan 26, 2026
* [CI] Add Claude GitHub actions (1technophile#2266)

* "Claude PR Assistant workflow"

* "Claude Code Review workflow"

* Add CLAUDE md for context

---------

Co-authored-by: Florian <1technophile@users.noreply.github.com>

* [DOCS] Bump qs and express (1technophile#2265)

Bumps [qs](https://github.com/ljharb/qs) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `qs` from 6.13.0 to 6.14.1
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](ljharb/qs@v6.13.0...v6.14.1)

Updates `express` from 4.21.1 to 4.22.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](expressjs/express@4.21.1...v4.22.1)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.14.1
  dependency-type: indirect
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* [CI] Configure Claude GitHub Actions to use Opus model (1technophile#2267)

* [CI] Configure Claude GitHub Actions to use Opus model

- Add --model opus flag to claude.yml workflow
- Add --model opus flag to claude-code-review.yml workflow
- Ensures advanced reasoning capabilities for complex firmware codebase

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Fix model ID to use full Claude Opus identifier

---------

Co-authored-by: Florian <1technophile@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

* [RF] Fix CC1101 initialization on boot with saved RF config (1technophile#2269)

When a saved RF configuration exists in NVS, loadFromStorage() was loading
the config but not calling iRFReceiver.enable(), which meant initCC1101()
was never invoked during boot. This caused the CC1101 to not receive signals
until the user manually toggled the RF receiver via the WebUI.

This fix adds a reinitReceiver parameter to loadFromStorage() that controls
whether to disable/enable the receiver after loading config. By default it's
true (for boot-time initialization), but loadFromMessage() passes false to
avoid double initialization when loading config from MQTT messages.

Fixes 1technophile#2264

Co-authored-by: Florian <1technophile@users.noreply.github.com>
Co-authored-by: Odyno <odyno@users.noreply.github.com>

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>

* [LORA] Fix syncword not persisting after reset (1technophile#2271)

The bug was a race condition where saved configuration was applied
to the LoRa hardware BEFORE LoRa.begin() was called, causing settings
like syncword to be lost after reset/power cycle.

Changes:
- Created LORAConfig_apply() to centralize hardware configuration
- Removed hardware application from LORAConfig_fromJson() (now only
  updates struct values)
- Call LORAConfig_apply() after LoRa.begin() in setupLORA()
- Call LORAConfig_apply() after LORAConfig_fromJson() in runtime
  handlers (MQTT/WebUI) since hardware is already initialized
- Fixed syncword logging to properly show 'unchanged' vs 'changed'

Fixes 1technophile#2270

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Florian <1technophile@users.noreply.github.com>

* Refactor GitHub Actions workflows for build, documentation, and linting

- Consolidated build logic into reusable workflows (`task-build.yml` and `task-docs.yml`) to reduce duplication across multiple workflows.
- Introduced `environments.json` to centralize the list of PlatformIO build environments, improving maintainability and clarity.
- Updated `build.yml` and `build_and_docs_to_dev.yml` to utilize the new reusable workflows and environment definitions.
- Enhanced `release.yml` to streamline the release process and integrate documentation generation.
- Created reusable linting workflow (`task-lint.yml`) to standardize code formatting checks across the repository.
- Simplified manual documentation workflow by leveraging the new reusable documentation workflow.
- Improved artifact management and retention policies across workflows.
- Updated dependencies and versions in workflows to ensure compatibility and performance.

* CI/CD pipeline agnostic of Workflow Engine and integrated on github actions

- Implemented ci.sh for orchestrating the complete build pipeline.
- Created ci_00_config.sh for centralized configuration of build scripts.
- Created ci_build_firmware.sh for building firmware for specified PlatformIO environments.
- Created ci_prepare_artifacts.sh for preparing firmware artifacts for upload or deployment.
- Created ci_set_version.sh for updating version tags in firmware configuration files.
- Created ci_build.sh to orchestrate the complete build pipeline.
- Created ci_qa.sh for code linting and formatting checks using clang-format.
- Created ci_site.sh for building and deploying VuePress documentation with version management.
- Implemented checks for required tools and dependencies in the new scripts.
- Improved internal scripts for better error handling and logging.

UPDATE the web installer manifest generation and update documentation structure
- Enhanced ci_list-env.sh to list environments from a JSON file.
- Replaced  common_wu.py and gen_wu.py scripts with new npm scripts for site generation and previewing on docsgen/gen_wu.js
- Replaced  generate_board_docs.py with docsgen/generated_board_docs.js
- Added new npm scripts for integration of site generation on build phase.
- Created preview_site.js to serve locally generated site over HTTPS with improved error handling.
- Added new CI environments for CI builds in environments.json.
- Deleted lint.yml as part of workflow cleanup.
- Enhanced task-build.yml to include linting as a job and added support for specifying PlatformIO version.
- Improved task-docs.yml to handle versioning more effectively and added clean option.

Enhance documentation
- ADD CLEAR Mark of development version of site
- Updated README.md to include detailed workflow dependencies and relationships using mermaid diagrams.
- Improved development.md with a quick checklist for contributors and clarified the code style guide.
- Enhanced quick_start.md with tips for contributors and streamlined the workflow explanation.

LINT FIX
- Refined User_config.h for better formatting consistency.
- Adjusted blufi.cpp and gatewayBT.cpp for improved code readability and consistency in formatting.
- Updated gatewaySERIAL.cpp and mqttDiscovery.cpp to enhance logging error messages.
- Improved sensorDS1820.cpp for better logging of device information.

* Add security scan workflows for vulnerability detection

Add SBOM generation and upload to release workflow; update security scan summary handling

Add shellcheck suppor + FIX shellcheck warning

Enhance documentation for CI/CD scripts and workflows, adding details for security scanning and SBOM generation processes

* Reviewed the full web board presentation and the ESP32 web upload. The project uses a modern pattern where data is divided from the presentation layer.

- Removed the `generate_board_docs` script.
- Updated the `gen_wu` script in order to generate `boards-info.json`: the fail that containe all information about the configuration
- Created and isolate the file `boards-info.js` to streamline the parsing of PlatformIO dependencies, modules, environments and improve the handling of library information.
- Introduced vuepress component `BoardEnvironmentTable.vue` that render `boards-info.json` as UI card component
- Introduced vuepress component `FlashEnvironmentSelector.vue` that render a selectred environment from  `boards-info.json` and provide esp-web-upload feature on it
- Introduced a new board page `board-selector.md` for improved firmware selection.
- Updated `web-install.md` to enhance the firmware upload process, including a new board environment table.
- Enhanced custom descriptions in `environments.ini` to include HTML links for better user guidance and board image link

* Add CC1101 initialization improvements and logging enhancements
Add installation step for PlatformIO dependencies in documentation workflow

* Remove unnecessary blank lines in GitHub Actions workflows documentation

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Florian <florian@theengs.io>
Co-authored-by: Florian <1technophile@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
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.

Changes between 1.8.1 and development breaks CC1101 (rcswitch / smartrc-cc1101-driver) default behaviour

1 participant