Skip to content

feat(visual): replace LED managers with LEDC-driven drivers#435

Merged
hhvrc merged 21 commits intodevelopfrom
feature/improve-led-managers
Mar 26, 2026
Merged

feat(visual): replace LED managers with LEDC-driven drivers#435
hhvrc merged 21 commits intodevelopfrom
feature/improve-led-managers

Conversation

@hhvrc
Copy link
Copy Markdown
Contributor

@hhvrc hhvrc commented Mar 26, 2026

Summary

  • Rename PinPatternManager/RGBPatternManager to MonoLedDriver/RgbLedDriver and move into src/visual/ + include/visual/
  • Replace raw GPIO toggling with ESP32 LEDC hardware PWM on the mono LED, enabling smooth 8-bit brightness control at 4 kHz
  • Use chip-agnostic LEDC speed mode (SOC_LEDC_SUPPORT_HS_MODE) so the same code builds across ESP32, S2, S3, and C3
  • Adopt FnProxy for FreeRTOS task creation from member functions, eliminating manual static_cast boilerplate

Test plan

  • Builds for Wemos-D1-Mini-ESP32 (mono LED only, original ESP32)
  • Builds for OpenShock-Core-V2 (both mono + WS2812B, ESP32-S3)
  • Builds for Wemos-Lolin-S3-Mini (WS2812B + SWAP_RG_CHANNELS, ESP32-S3)
  • Flash and verify mono LED blink patterns at default brightness
  • Flash and verify SetBrightness() visibly dims the mono LED
  • Verify WS2812B RGB patterns unchanged on a board with both LED types
  • Verify E-Stop visual states (Active, ActiveClearing, AwaitingRelease) display correctly

hhvrc and others added 18 commits August 22, 2024 14:08
Resolve merge conflicts keeping MonoLedDriver/RgbLedDriver renames while
adopting develop's improvements: atomic state flags, cooperative task
shutdown, SimpleMutex wrappers, EStopState::ActiveClearing, IP event
handler, CSR_PATTERN macro, and thread-safe gateway connection management.

Fix MonoLedDriver LEDC speed mode to be chip-agnostic (SOC_LEDC_SUPPORT_HS_MODE),
add missing ledc_update_duty call, and correct FnProxy usage (no address-of on
variable template).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hhvrc hhvrc self-assigned this Mar 26, 2026
Copilot AI review requested due to automatic review settings March 26, 2026 21:32
@github-project-automation github-project-automation bot moved this to Todo in Roadmap Mar 26, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 26, 2026

🦋 Changeset detected

Latest commit: 307fc02

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 13 out of 14 changed files in this pull request and generated no comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

Cpp-Linter Report ⚠️

Some files did not pass the configured checks!

clang-format (v21.1.8) reports: 5 file(s) not formatted
  • src/GatewayClient.cpp
  • src/GatewayConnectionManager.cpp
  • src/main.cpp
  • src/visual/VisualStateManager.cpp
  • src/wifi/WiFiManager.cpp
clang-tidy (v21.1.8) reports: 289 concern(s)
  • include/serial/command_handlers/index.h:1:1: warning: [portability-avoid-pragma-once]

    avoid 'pragma once' directive; use include guards instead

        1 | #pragma once
          | ^
  • include/serial/command_handlers/index.h:8:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

        8 |   OpenShock::Serial::CommandGroup VersionHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^               
          |   auto                                             -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:9:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

        9 |   OpenShock::Serial::CommandGroup RestartHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^               
          |   auto                                             -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:10:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       10 |   OpenShock::Serial::CommandGroup SysInfoHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^               
          |   auto                                             -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:11:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       11 |   OpenShock::Serial::CommandGroup EchoHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^            
          |   auto                                          -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:12:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       12 |   OpenShock::Serial::CommandGroup ValidGpiosHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^                  
          |   auto                                                -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:13:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       13 |   OpenShock::Serial::CommandGroup RfTxPinHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^               
          |   auto                                             -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:14:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       14 |   OpenShock::Serial::CommandGroup EStopHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^             
          |   auto                                           -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:15:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       15 |   OpenShock::Serial::CommandGroup DomainHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^              
          |   auto                                            -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:16:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       16 |   OpenShock::Serial::CommandGroup AuthTokenHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^                 
          |   auto                                               -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:17:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       17 |   OpenShock::Serial::CommandGroup HostnameHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^                
          |   auto                                              -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:18:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       18 |   OpenShock::Serial::CommandGroup NetworksHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^                
          |   auto                                              -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:19:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       19 |   OpenShock::Serial::CommandGroup KeepAliveHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^                 
          |   auto                                               -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:20:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       20 |   OpenShock::Serial::CommandGroup JsonConfigHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^                  
          |   auto                                                -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:21:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       21 |   OpenShock::Serial::CommandGroup RawConfigHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^                 
          |   auto                                               -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:22:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       22 |   OpenShock::Serial::CommandGroup RfTransmitHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^                  
          |   auto                                                -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:23:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       23 |   OpenShock::Serial::CommandGroup FactoryResetHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^                    
          |   auto                                                  -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:24:35: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       24 |   OpenShock::Serial::CommandGroup LedTestHandler();
          |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^               
          |   auto                                             -> OpenShock::Serial::CommandGroup
  • include/serial/command_handlers/index.h:26:55: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       26 |   inline std::vector<OpenShock::Serial::CommandGroup> AllCommandHandlers()
          |                                                       ^
  • include/visual/MonoLedDriver.h:1:1: warning: [portability-avoid-pragma-once]

    avoid 'pragma once' directive; use include guards instead

        1 | #pragma once
          | ^
  • include/visual/MonoLedDriver.h:17:5: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       17 |     DISABLE_COPY(MonoLedDriver);
          |     ^
    include/Common.h:9:13: note: expanded from macro 'DISABLE_COPY'
        9 |   TypeName& operator=(const TypeName&) = delete
          |             ^
  • include/visual/MonoLedDriver.h:18:5: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       18 |     DISABLE_MOVE(MonoLedDriver);
          |     ^
    include/Common.h:12:13: note: expanded from macro 'DISABLE_MOVE'
       12 |   TypeName& operator=(TypeName&&) = delete
          |             ^
  • include/visual/MonoLedDriver.h:21:12: warning: [cppcoreguidelines-pro-type-member-init]

    constructor does not initialize these fields: level, duration

       21 |     struct State {
          |            ^
       22 |       bool level;
          |                 
          |                 {}
       23 |       uint32_t duration;
          |                        
          |                        {}
  • include/visual/MonoLedDriver.h:29:5: warning: [modernize-use-nodiscard]

    function 'IsValid' should be marked [[nodiscard]]

       29 |     bool IsValid() const { return m_gpioPin != GPIO_NUM_NC; }
          |     ^
          |     [[nodiscard]] 
  • include/visual/MonoLedDriver.h:29:10: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       29 |     bool IsValid() const { return m_gpioPin != GPIO_NUM_NC; }
          |     ~~~~ ^
          |     auto                 -> bool
  • include/visual/MonoLedDriver.h:33:5: warning: [readability-redundant-inline-specifier]

    function 'SetPattern' has inline specifier but is implicitly inlined

       33 |     inline void SetPattern(const State (&pattern)[N])
          |     ^~~~~~
  • include/visual/MonoLedDriver.h:33:34: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       33 |     inline void SetPattern(const State (&pattern)[N])
          |                                  ^
  • include/visual/RgbLedDriver.h:1:1: warning: [portability-avoid-pragma-once]

    avoid 'pragma once' directive; use include guards instead

        1 | #pragma once
          | ^
  • include/visual/RgbLedDriver.h:19:5: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       19 |     DISABLE_COPY(RgbLedDriver);
          |     ^
    include/Common.h:9:13: note: expanded from macro 'DISABLE_COPY'
        9 |   TypeName& operator=(const TypeName&) = delete
          |             ^
  • include/visual/RgbLedDriver.h:20:5: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       20 |     DISABLE_MOVE(RgbLedDriver);
          |     ^
    include/Common.h:12:13: note: expanded from macro 'DISABLE_MOVE'
       12 |   TypeName& operator=(TypeName&&) = delete
          |             ^
  • include/visual/RgbLedDriver.h:26:5: warning: [modernize-use-nodiscard]

    function 'IsValid' should be marked [[nodiscard]]

       26 |     bool IsValid() const { return m_gpioPin != GPIO_NUM_NC; }
          |     ^
          |     [[nodiscard]] 
  • include/visual/RgbLedDriver.h:26:10: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       26 |     bool IsValid() const { return m_gpioPin != GPIO_NUM_NC; }
          |     ~~~~ ^
          |     auto                 -> bool
  • include/visual/RgbLedDriver.h:28:12: warning: [cppcoreguidelines-pro-type-member-init]

    constructor does not initialize these fields: red, green, blue, duration

       28 |     struct RGBState {
          |            ^
       29 |       uint8_t red;
          |                  
          |                  {}
       30 |       uint8_t green;
          |                    
          |                    {}
       31 |       uint8_t blue;
          |                   
          |                   {}
       32 |       uint32_t duration;
          |                        
          |                        {}
  • include/visual/RgbLedDriver.h:37:5: warning: [readability-redundant-inline-specifier]

    function 'SetPattern' has inline specifier but is implicitly inlined

       37 |     inline void SetPattern(const RGBState (&pattern)[N])
          |     ^~~~~~
  • include/visual/RgbLedDriver.h:37:34: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       37 |     inline void SetPattern(const RGBState (&pattern)[N])
          |                                  ^
  • include/visual/VisualStateManager.h:1:1: warning: [portability-avoid-pragma-once]

    avoid 'pragma once' directive; use include guards instead

        1 | #pragma once
          | ^
  • include/visual/VisualStateManager.h:7:22: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

        7 |   [[nodiscard]] bool Init();
          |                 ~~~~ ^     
          |                 auto        -> bool
  • src/GatewayClient.cpp:17:13: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_bootStatusSent' is non-const and globally accessible, consider making it const

       17 | static bool s_bootStatusSent = false;
          |             ^
  • src/GatewayClient.cpp:41:29: warning: [bugprone-easily-swappable-parameters]

    3 adjacent parameters of 'connect' of similar type are easily swapped by mistake

       41 | void GatewayClient::connect(const std::string& host, uint16_t port, const std::string& path)
          |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/GatewayClient.cpp:41:48: note: the first parameter in the range is 'host'
       41 | void GatewayClient::connect(const std::string& host, uint16_t port, const std::string& path)
          |                                                ^~~~
    src/GatewayClient.cpp:41:88: note: the last parameter in the range is 'path'
       41 | void GatewayClient::connect(const std::string& host, uint16_t port, const std::string& path)
          |                                                                                        ^~~~
    src/GatewayClient.cpp:41:54: note: 'const int &' and 'int' parameters accept and bind the same kind of values
       41 | void GatewayClient::connect(const std::string& host, uint16_t port, const std::string& path)
          |                                                      ^
  • src/GatewayClient.cpp:75:21: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       75 | bool GatewayClient::sendMessageTXT(std::string_view data)
          | ~~~~                ^                                    
          | auto                                                      -> bool
  • src/GatewayClient.cpp:84:21: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       84 | bool GatewayClient::sendMessageBIN(tcb::span<const uint8_t> data)
          | ~~~~                ^                                            
          | auto                                                              -> bool
  • src/GatewayClient.cpp:93:21: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       93 | bool GatewayClient::loop()
          | ~~~~                ^     
          | auto                       -> bool
  • src/GatewayClient.cpp:118:3: warning: [cppcoreguidelines-avoid-do-while]

    avoid do-while loops

      118 |   ESP_ERROR_CHECK(esp_event_post(OPENSHOCK_EVENTS, OPENSHOCK_EVENT_GATEWAY_CLIENT_STATE_CHANGED, &m_state, sizeof(m_state), portMAX_DELAY));
          |   ^
    /home/runner/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32s3/include/esp_common/include/esp_err.h:115:28: note: expanded from macro 'ESP_ERROR_CHECK'
      115 | #define ESP_ERROR_CHECK(x) do {                                         \
          |                            ^
  • src/GatewayClient.cpp:123:24: warning: [readability-braces-around-statements]

    statement should be inside braces

      123 |   if (s_bootStatusSent) return;
          |                        ^       
          |                         {
  • src/GatewayClient.cpp:133:28: warning: [cppcoreguidelines-init-variables]

    variable 'updateStep' is not initialized

      133 |   OpenShock::OtaUpdateStep updateStep;
          |                            ^
  • src/GatewayClient.cpp:147:124: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this lambda

      147 |   s_bootStatusSent = Serialization::Gateway::SerializeBootStatusMessage(updateId, OtaUpdateManager::GetFirmwareBootType(), [this](tcb::span<const uint8_t> data) { return m_webSocket.sendBIN(data.data(), data.size()); });
          |                                                                                                                            ^
          |                                                                                                                                                                  -> void
  • src/GatewayConnectionManager.cpp:43:29: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_flags' is non-const and globally accessible, consider making it const

       43 | static std::atomic<uint8_t> s_flags                 = 0;
          |                             ^
  • src/GatewayConnectionManager.cpp:44:29: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_lastAuthFailure' is non-const and globally accessible, consider making it const

       44 | static std::atomic<int64_t> s_lastAuthFailure       = 0;
          |                             ^
  • src/GatewayConnectionManager.cpp:45:29: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_lastConnectionAttempt' is non-const and globally accessible, consider making it const

       45 | static std::atomic<int64_t> s_lastConnectionAttempt = 0;
          |                             ^
  • src/GatewayConnectionManager.cpp:46:25: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_isInitializing' is non-const and globally accessible, consider making it const

       46 | static std::atomic_flag s_isInitializing            = ATOMIC_FLAG_INIT;
          |                         ^
  • src/GatewayConnectionManager.cpp:47:31: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_clientMutex' is non-const and globally accessible, consider making it const

       47 | static OpenShock::SimpleMutex s_clientMutex;
          |                               ^
  • src/GatewayConnectionManager.cpp:48:50: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_wsClient' is non-const and globally accessible, consider making it const

       48 | static std::shared_ptr<OpenShock::GatewayClient> s_wsClient = nullptr;
          |                                                  ^
  • src/GatewayConnectionManager.cpp:50:50: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       50 | static std::shared_ptr<OpenShock::GatewayClient> GetClient()
          |                                                  ^
  • src/GatewayConnectionManager.cpp:52:25: warning: [bugprone-reserved-identifier]

    declaration uses identifier 'lock__', which is a reserved identifier

       52 |   OpenShock::ScopedLock lock__(&s_clientMutex);
          |                         ^~~~~~
          |                         lock_
  • src/GatewayConnectionManager.cpp:57:25: warning: [bugprone-reserved-identifier]

    declaration uses identifier 'lock__', which is a reserved identifier

       57 |   OpenShock::ScopedLock lock__(&s_clientMutex);
          |                         ^~~~~~
          |                         lock_
  • src/GatewayConnectionManager.cpp:62:25: warning: [bugprone-reserved-identifier]

    declaration uses identifier 'lock__', which is a reserved identifier

       62 |   OpenShock::ScopedLock lock__(&s_clientMutex);
          |                         ^~~~~~
          |                         lock_
  • src/GatewayConnectionManager.cpp:83:13: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       83 | static bool checkIsDeAuthRateLimited(int64_t millis)
          |        ~~~~ ^                                       
          |        auto                                          -> bool
  • src/GatewayConnectionManager.cpp:85:67: warning: [cppcoreguidelines-avoid-magic-numbers]

    300'000 is a magic number; consider replacing it with a named constant

       85 |   return s_lastAuthFailure != 0 && (millis - s_lastAuthFailure) < 300'000;  // 5 Minutes
          |                                                                   ^
  • src/GatewayConnectionManager.cpp:87:13: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       87 | static bool checkIsConnectionRateLimited(int64_t millis)
          |        ~~~~ ^                                           
          |        auto                                              -> bool
  • src/GatewayConnectionManager.cpp:89:79: warning: [cppcoreguidelines-avoid-magic-numbers]

    20'000 is a magic number; consider replacing it with a named constant

       89 |   return s_lastConnectionAttempt != 0 && (millis - s_lastConnectionAttempt) < 20'000;  // 20 seconds
          |                                                                               ^
  • src/GatewayConnectionManager.cpp:95:32: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       95 | bool GatewayConnectionManager::Init()
          | ~~~~                           ^     
          | auto                                  -> bool
  • src/GatewayConnectionManager.cpp:104:32: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

      104 | bool GatewayConnectionManager::IsConnected()
          | ~~~~                           ^            
          | auto                                         -> bool
  • src/GatewayConnectionManager.cpp:114:32: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

      114 | bool GatewayConnectionManager::IsLinked()
          | ~~~~                           ^         
          | auto                                      -> bool
  • src/GatewayConnectionManager.cpp:119:49: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

      119 | AccountLinkResultCode GatewayConnectionManager::Link(std::string_view linkCode)
          | ~~~~~~~~~~~~~~~~~~~~~                           ^                              
          | auto                                                                            -> AccountLinkResultCode
  • src/GatewayConnectionManager.cpp:136:24: warning: [cppcoreguidelines-avoid-magic-numbers]

    404 is a magic number; consider replacing it with a named constant

      136 |   if (response.code == 404) {
          |                        ^
  • src/GatewayConnectionManager.cpp:150:24: warning: [cppcoreguidelines-avoid-magic-numbers]

    200 is a magic number; consider replacing it with a named constant

      150 |   if (response.code != 200) {
          |                        ^
  • src/GatewayConnectionManager.cpp:177:32: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

      177 | bool GatewayConnectionManager::SendMessageTXT(std::string_view data)
          | ~~~~                           ^                                    
          | auto                                                                 -> bool
  • src/GatewayConnectionManager.cpp:187:32: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

      187 | bool GatewayConnectionManager::SendMessageBIN(tcb::span<const uint8_t> data)
          | ~~~~                           ^                                            
          | auto                                                                         -> bool
  • src/GatewayConnectionManager.cpp:197:6: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

      197 | bool FetchHubInfo(std::string authToken)
          | ~~~~ ^                                  
          | auto                                     -> bool
  • src/GatewayConnectionManager.cpp:210:24: warning: [cppcoreguidelines-avoid-magic-numbers]

    401 is a magic number; consider replacing it with a named constant

      210 |   if (response.code == 401) {
          |                        ^
  • src/GatewayConnectionManager.cpp:224:24: warning: [cppcoreguidelines-avoid-magic-numbers]

    200 is a magic number; consider replacing it with a named constant

      224 |   if (response.code != 200) {
          |                        ^
  • src/GatewayConnectionManager.cpp:241:6: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

      241 | bool StartConnectingToLCG()
          | ~~~~ ^                     
          | auto                        -> bool
  • src/GatewayConnectionManager.cpp:274:24: warning: [cppcoreguidelines-avoid-magic-numbers]

    401 is a magic number; consider replacing it with a named constant

      274 |   if (response.code == 401) {
          |                        ^
  • src/GatewayConnectionManager.cpp:288:24: warning: [cppcoreguidelines-avoid-magic-numbers]

    200 is a magic number; consider replacing it with a named constant

      288 |   if (response.code != 200) {
          |                        ^
  • src/main.cpp:25:6: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       25 | bool trySetup()
          | ~~~~ ^         
          | auto            -> bool
  • src/main.cpp:95:19: warning: [cppcoreguidelines-avoid-magic-numbers]

    115'200 is a magic number; consider replacing it with a named constant

       95 |   OS_SERIAL.begin(115'200);
          |                   ^
  • src/main.cpp:98:23: warning: [cppcoreguidelines-avoid-magic-numbers]

    115'200 is a magic number; consider replacing it with a named constant

       98 |   OS_SERIAL_USB.begin(115'200);
          |                       ^
  • src/main.cpp:123:16: warning: [cppcoreguidelines-avoid-magic-numbers]

    5 is a magic number; consider replacing it with a named constant

      123 |     vTaskDelay(5);  // 5 ticks update interval
          |                ^
  • src/main.cpp:130:71: warning: [cppcoreguidelines-avoid-magic-numbers]

    8192 is a magic number; consider replacing it with a named constant

      130 |   if (OpenShock::TaskUtils::TaskCreateExpensive(main_app, "main_app", 8192, nullptr, 1, nullptr) != pdPASS) {  // PROFILED: 6KB stack usage
          |                                                                       ^
  • src/serial/command_handlers/ledtest.cpp:5:6: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_handleSerialLedTestCommand', which is reserved in the global namespace

        5 | void _handleSerialLedTestCommand(std::string_view arg, bool isAutomated)
          |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
          |      handleSerialLedTestCommand
  • src/serial/command_handlers/ledtest.cpp:10:3: warning: [cppcoreguidelines-pro-type-vararg]

    do not call c-style vararg functions

       10 |   SERPR_RESPONSE("LedTest|Starting LED test (~24s)...");
          |   ^
    include/serial/command_handlers/common.h:20:37: note: expanded from macro 'SERPR_RESPONSE'
       20 | #define SERPR_RESPONSE(format, ...) SERPR_SYS("Response|" format, ##__VA_ARGS__)
          |                                     ^
    include/serial/command_handlers/common.h:14:19: note: expanded from macro 'SERPR_SYS'
       14 |     OS_SERIAL_USB.printf("$SYS$|" format "\r\n", ##__VA_ARGS__); \
          |                   ^
  • src/serial/command_handlers/ledtest.cpp:14:3: warning: [cppcoreguidelines-pro-type-vararg]

    do not call c-style vararg functions

       14 |   SERPR_SUCCESS("LedTest|Complete");
          |   ^
    include/serial/command_handlers/common.h:21:37: note: expanded from macro 'SERPR_SUCCESS'
       21 | #define SERPR_SUCCESS(format, ...)  SERPR_SYS("Success|" format, ##__VA_ARGS__)
          |                                     ^
    include/serial/command_handlers/common.h:14:19: note: expanded from macro 'SERPR_SYS'
       14 |     OS_SERIAL_USB.printf("$SYS$|" format "\r\n", ##__VA_ARGS__); \
          |                   ^
  • src/serial/command_handlers/ledtest.cpp:17:69: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       17 | OpenShock::Serial::CommandGroup OpenShock::Serial::CommandHandlers::LedTestHandler()
          | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                     ^               
          | auto                                                                                 -> OpenShock::Serial::CommandGroup
  • src/visual/MonoLedDriver.cpp:22:1: warning: [cppcoreguidelines-macro-to-enum]

    replace macro with enum

       22 | #define OS_LEDC_FREQUENCY  4000  // https://en.wikipedia.org/wiki/Flicker_fusion_threshold
          | ^~~~~~~
          |                           =
       23 | 
  • src/visual/MonoLedDriver.cpp:22:9: warning: [cppcoreguidelines-macro-to-enum]

    macro 'OS_LEDC_FREQUENCY' defines an integral constant; prefer an enum instead

       22 | #define OS_LEDC_FREQUENCY  4000  // https://en.wikipedia.org/wiki/Flicker_fusion_threshold
          |         ^
  • src/visual/MonoLedDriver.cpp:22:9: warning: [cppcoreguidelines-macro-usage]

    macro 'OS_LEDC_FREQUENCY' used to declare a constant; consider using a 'constexpr' constant

  • src/visual/MonoLedDriver.cpp:26:1: warning: [cppcoreguidelines-pro-type-member-init]

    constructor does not initialize these fields: m_brightness, m_pattern

       26 | MonoLedDriver::MonoLedDriver(gpio_num_t gpioPin)
          | ^
  • src/visual/MonoLedDriver.cpp:31:5: warning: [readability-redundant-member-init]

    initializer for member 'm_taskMutex' is redundant

       31 |   , m_taskMutex()
          |     ^~~~~~~~~~~~~
  • src/visual/MonoLedDriver.cpp:85:3: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       85 |   char name[32];
          |   ^
  • src/visual/MonoLedDriver.cpp:85:13: warning: [cppcoreguidelines-avoid-magic-numbers]

    32 is a magic number; consider replacing it with a named constant

       85 |   char name[32];
          |             ^
  • src/visual/MonoLedDriver.cpp:90:103: warning: [cppcoreguidelines-avoid-magic-numbers]

    1024 is a magic number; consider replacing it with a named constant

       90 |   BaseType_t result = TaskUtils::TaskCreateUniversal(Util::FnProxy<&MonoLedDriver::RunPattern>, name, 1024, this, 1, &m_taskHandle, 1);  // PROFILED: 0.5KB stack usage
          |                                                                                                       ^
  • src/visual/MonoLedDriver.cpp:126:21: warning: [readability-convert-member-functions-to-static]

    method 'RunPattern' can be made static

      126 | void MonoLedDriver::RunPattern()
          |                     ^
  • src/visual/RgbLedDriver.cpp:20:1: warning: [cppcoreguidelines-pro-type-member-init]

    constructor does not initialize these fields: m_brightness, m_pattern

       20 | RgbLedDriver::RgbLedDriver(gpio_num_t gpioPin)
          | ^
  • src/visual/RgbLedDriver.cpp:26:5: warning: [readability-redundant-member-init]

    initializer for member 'm_taskMutex' is redundant

       26 |   , m_taskMutex()
          |     ^~~~~~~~~~~~~
  • src/visual/RgbLedDriver.cpp:39:22: warning: [modernize-use-nullptr]

    use nullptr

       39 |   if (m_rmtHandle == NULL) {
          |                      ^~~~
          |                      nullptr
  • src/visual/RgbLedDriver.cpp:69:101: warning: [cppcoreguidelines-avoid-magic-numbers]

    4096 is a magic number; consider replacing it with a named constant

       69 |   BaseType_t result = TaskUtils::TaskCreateExpensive(Util::FnProxy<&RgbLedDriver::RunPattern>, TAG, 4096, this, 1, &m_taskHandle);  // PROFILED: 1.7KB stack usage
          |                                                                                                     ^
  • src/visual/RgbLedDriver.cpp:106:20: warning: [readability-convert-member-functions-to-static]

    method 'RunPattern' can be made static

      106 | void RgbLedDriver::RunPattern()
          |                    ^
  • src/visual/VisualStateManager.cpp:36:30: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_stateFlags' is non-const and globally accessible, consider making it const

       36 | static std::atomic<uint64_t> s_stateFlags = 0;
          |                              ^
  • src/visual/VisualStateManager.cpp:37:50: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_monoLedDriver' is non-const and globally accessible, consider making it const

       37 | static std::unique_ptr<OpenShock::MonoLedDriver> s_monoLedDriver;
          |                                                  ^
  • src/visual/VisualStateManager.cpp:38:49: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 's_rgbLedDriver' is non-const and globally accessible, consider making it const

       38 | static std::unique_ptr<OpenShock::RgbLedDriver> s_rgbLedDriver;
          |                                                 ^
  • src/visual/VisualStateManager.cpp:40:13: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_setStateFlag', which is reserved in the global namespace

       40 | inline void _setStateFlag(uint64_t flag, bool state)
          |             ^~~~~~~~~~~~~
          |             setStateFlag
  • src/visual/VisualStateManager.cpp:49:13: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_isStateFlagSet', which is reserved in the global namespace

       49 | inline bool _isStateFlagSet(uint64_t flag)
          |             ^~~~~~~~~~~~~~~
          |             isStateFlagSet
  • src/visual/VisualStateManager.cpp:49:13: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

       49 | inline bool _isStateFlagSet(uint64_t flag)
          |        ~~~~ ^                             
          |        auto                                -> bool
  • src/visual/VisualStateManager.cpp:56:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       56 | const MonoLedDriver::State kCriticalErrorPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:60:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       60 | const RgbLedDriver::RGBState kCriticalErrorRGBPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:65:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       65 | const MonoLedDriver::State kEmergencyStoppedPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:69:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       69 | const RgbLedDriver::RGBState kEmergencyStoppedRGBPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:74:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       74 | const MonoLedDriver::State kEmergencyStopActiveClearingPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:79:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       79 | const RgbLedDriver::RGBState kEmergencyStopActiveClearingRGBPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:90:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       90 | const MonoLedDriver::State kEmergencyStopAwaitingReleasePattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:95:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       95 | const RgbLedDriver::RGBState kEmergencyStopAwaitingReleaseRGBPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:100:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      100 | const MonoLedDriver::State kWiFiDisconnectedPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:108:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      108 | const RgbLedDriver::RGBState kWiFiDisconnectedRGBPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:117:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      117 | const MonoLedDriver::State kWiFiConnectedWithoutWSPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:123:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      123 | const RgbLedDriver::RGBState kWiFiConnectedWithoutWSRGBPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:130:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      130 | const MonoLedDriver::State kPingNoResponsePattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:140:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      140 | const RgbLedDriver::RGBState kPingNoResponseRGBPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:151:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      151 | const MonoLedDriver::State kWebSocketCantConnectPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:163:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      163 | const RgbLedDriver::RGBState kWebSocketCantConnectRGBPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:176:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      176 | const MonoLedDriver::State kWebSocketConnectedPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:180:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      180 | const RgbLedDriver::RGBState kWebSocketConnectedRGBPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:185:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      185 | const MonoLedDriver::State kSolidOnPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:189:7: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      189 | const MonoLedDriver::State kSolidOffPattern[] = {
          |       ^
  • src/visual/VisualStateManager.cpp:194:13: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_updateVisualStateGPIO', which is reserved in the global namespace

      194 | inline void _updateVisualStateGPIO(const MonoLedDriver::State (&override)[N])
          |             ^~~~~~~~~~~~~~~~~~~~~~
          |             updateVisualStateGPIO
  • src/visual/VisualStateManager.cpp:194:42: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      194 | inline void _updateVisualStateGPIO(const MonoLedDriver::State (&override)[N])
          |                                          ^
  • src/visual/VisualStateManager.cpp:200:9: warning: [cppcoreguidelines-macro-usage]

    function-like macro 'CSR_PATTERN' used; consider a 'constexpr' template function

      200 | #define CSR_PATTERN(manager, flag, pattern) \
          |         ^
  • src/visual/VisualStateManager.cpp:202:5: warning: [bugprone-macro-parentheses]

    macro argument should be enclosed in parentheses

      202 |     manager->SetPattern(pattern);           \
          |     ^      
          |     (      )
  • src/visual/VisualStateManager.cpp:206:6: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_updateVisualStateGPIO', which is reserved in the global namespace

      206 | void _updateVisualStateGPIO()
          |      ^~~~~~~~~~~~~~~~~~~~~~
          |      updateVisualStateGPIO
  • src/visual/VisualStateManager.cpp:219:6: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_updateVisualStateRGB', which is reserved in the global namespace

      219 | void _updateVisualStateRGB()
          |      ^~~~~~~~~~~~~~~~~~~~~
          |      updateVisualStateRGB
  • src/visual/VisualStateManager.cpp:232:6: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_updateVisualState', which is reserved in the global namespace

      232 | void _updateVisualState()
          |      ^~~~~~~~~~~~~~~~~~
          |      updateVisualState
  • src/visual/VisualStateManager.cpp:260:6: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_handleEspWiFiEvent', which is reserved in the global namespace

      260 | void _handleEspWiFiEvent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
          |      ^~~~~~~~~~~~~~~~~~~
          |      handleEspWiFiEvent
  • src/visual/VisualStateManager.cpp:288:6: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_handleEspIpEvent', which is reserved in the global namespace

      288 | void _handleEspIpEvent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
          |      ^~~~~~~~~~~~~~~~~
          |      handleEspIpEvent
  • src/visual/VisualStateManager.cpp:317:6: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_handleOpenShockEStopStateChanged', which is reserved in the global namespace

      317 | void _handleOpenShockEStopStateChanged(void* event_data)
          |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          |      handleOpenShockEStopStateChanged
  • src/visual/VisualStateManager.cpp:326:6: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_handleOpenShockGatewayStateChanged', which is reserved in the global namespace

      326 | void _handleOpenShockGatewayStateChanged(void* event_data)
          |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          |      handleOpenShockGatewayStateChanged
  • src/visual/VisualStateManager.cpp:333:6: warning: [bugprone-reserved-identifier]

    declaration uses identifier '_handleOpenShockEvent', which is reserved in the global namespace

      333 | void _handleOpenShockEvent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
          |      ^~~~~~~~~~~~~~~~~~~~~
          |      handleOpenShockEvent
  • src/visual/VisualStateManager.cpp:357:26: warning: [modernize-use-trailing-return-type]

    use a trailing return type for this function

      357 | bool VisualStateManager::Init()
          | ~~~~                     ^     
          | auto                            -> bool
  • src/visual/VisualStateManager.cpp:376:35: warning: [cppcoreguidelines-avoid-magic-numbers]

    20 is a magic number; consider replacing it with a named constant

      376 |     s_rgbLedDriver->SetBrightness(20);
          |                                   ^
  • src/visual/VisualStateManager.cpp:445:18: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      445 |     static const MonoLedDriver::State solidOn[] = {
          |                  ^
  • src/visual/VisualStateManager.cpp:448:5: warning: [bugprone-infinite-loop]

    this loop is infinite; none of its condition variables (b) are updated in the loop body

      448 |     for (uint16_t b = 0; b <= 255; b += 5) {
          |     ^
  • src/visual/VisualStateManager.cpp:448:19: warning: [readability-identifier-length]

    loop variable name 'b' is too short, expected at least 2 characters

      448 |     for (uint16_t b = 0; b <= 255; b += 5) {
          |                   ^
  • src/visual/VisualStateManager.cpp:448:31: warning: [cppcoreguidelines-avoid-magic-numbers]

    255 is a magic number; consider replacing it with a named constant

      448 |     for (uint16_t b = 0; b <= 255; b += 5) {
          |                               ^
  • src/visual/VisualStateManager.cpp:448:41: warning: [cppcoreguidelines-avoid-magic-numbers]

    5 is a magic number; consider replacing it with a named constant

      448 |     for (uint16_t b = 0; b <= 255; b += 5) {
          |                                         ^
  • src/visual/VisualStateManager.cpp:455:5: warning: [bugprone-infinite-loop]

    this loop is infinite; none of its condition variables (b) are updated in the loop body

      455 |     for (int16_t b = 255; b >= 0; b -= 5) {
          |     ^
  • src/visual/VisualStateManager.cpp:455:18: warning: [readability-identifier-length]

    loop variable name 'b' is too short, expected at least 2 characters

      455 |     for (int16_t b = 255; b >= 0; b -= 5) {
          |                  ^
  • src/visual/VisualStateManager.cpp:455:22: warning: [cppcoreguidelines-avoid-magic-numbers]

    255 is a magic number; consider replacing it with a named constant

      455 |     for (int16_t b = 255; b >= 0; b -= 5) {
          |                      ^
  • src/visual/VisualStateManager.cpp:455:40: warning: [cppcoreguidelines-avoid-magic-numbers]

    5 is a magic number; consider replacing it with a named constant

      455 |     for (int16_t b = 255; b >= 0; b -= 5) {
          |                                        ^
  • src/visual/VisualStateManager.cpp:462:36: warning: [cppcoreguidelines-avoid-magic-numbers]

    255 is a magic number; consider replacing it with a named constant

      462 |     s_monoLedDriver->SetBrightness(255);
          |                                    ^
  • src/visual/VisualStateManager.cpp:469:31: warning: [cppcoreguidelines-avoid-magic-numbers]

    20 is a magic number; consider replacing it with a named constant

      469 |     uint8_t savedBrightness = 20;  // default from Init()
          |                               ^
  • src/visual/VisualStateManager.cpp:471:35: warning: [cppcoreguidelines-avoid-magic-numbers]

    255 is a magic number; consider replacing it with a named constant

      471 |     s_rgbLedDriver->SetBrightness(255);
          |                                   ^
  • src/visual/VisualStateManager.cpp:474:18: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      474 |     static const RgbLedDriver::RGBState red[] = {
          |                  ^
  • src/visual/VisualStateManager.cpp:481:18: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      481 |     static const RgbLedDriver::RGBState green[] = {
          |                  ^
  • src/visual/VisualStateManager.cpp:488:18: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      488 |     static const RgbLedDriver::RGBState blue[] = {
          |                  ^
  • src/visual/VisualStateManager.cpp:495:18: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      495 |     static const RgbLedDriver::RGBState white[] = {
          |                  ^
  • src/visual/VisualStateManager.cpp:502:18: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      502 |     static const RgbLedDriver::RGBState cycle[] = {
          |                  ^
  • src/visual/VisualStateManager.cpp:516:18: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

      516 |     static const RgbLedDriver::RGBState solidWhite[] = {
          |                  ^
  • src/visual/VisualStateManager.cpp:519:5: warning: [bugprone-infinite-loop]

    this loop is infinite; none of its condition variables (b) are updated in the loop body

      519 |     for (uint16_t b = 0; b <= 255; b += 5) {
          |     ^

Have any feedback or feature suggestions? Share it here.

hhvrc and others added 2 commits March 26, 2026 22:40
…tdown

Add serial command `ledtest` that cycles through:
- Mono LED PWM brightness sweep (up/down)
- RGB LED color test (R/G/B/white, rainbow cycle, brightness sweep)
- All visual state patterns (WiFi, WS, E-Stop states, critical error)

Fix cooperative task shutdown in both LED drivers by chunking long
vTaskDelay calls into 50ms intervals, allowing m_stopRequested to be
checked promptly instead of force-killing tasks after timeout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hhvrc hhvrc merged commit 9024872 into develop Mar 26, 2026
40 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in Roadmap Mar 26, 2026
@hhvrc hhvrc deleted the feature/improve-led-managers branch March 26, 2026 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants