Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 106 additions & 10 deletions .github/workflows/usermods.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ on:
pull_request:
paths:
- usermods/**
push:
paths:
- usermods/**
Comment on lines 4 to +9
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Broaden the path filter to cover the files that define this CI behavior.

Right now this workflow only fires for usermods/**, so changes to .github/workflows/usermods.yml or platformio_override.sample.ini can skip the very checks they affect.

Suggested change
 on:
   pull_request:
     paths:
       - usermods/**
+      - .github/workflows/usermods.yml
+      - platformio_override.sample.ini
   push:
     paths:
       - usermods/**
+      - .github/workflows/usermods.yml
+      - platformio_override.sample.ini

As per coding guidelines, "Follow the CI/CD conventions documented in docs/cicd.instructions.md."

📝 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
pull_request:
paths:
- usermods/**
push:
paths:
- usermods/**
pull_request:
paths:
- usermods/**
- .github/workflows/usermods.yml
- platformio_override.sample.ini
push:
paths:
- usermods/**
- .github/workflows/usermods.yml
- platformio_override.sample.ini
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/usermods.yml around lines 4 - 9, The path filters under
the pull_request and push triggers in .github/workflows/usermods.yml currently
only include "usermods/**" which allows changes to the workflow file or related
config to bypass the workflow; update the triggers (the pull_request: paths: and
push: paths: entries) to also include the workflow file itself
(".github/workflows/usermods.yml") and the configuration sample
("platformio_override.sample.ini") so changes to those files will run the
workflow; adjust the paths list entries accordingly to include these two file
patterns alongside "usermods/**".


env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
Expand All @@ -12,28 +15,40 @@ jobs:

get_usermod_envs:
# Only run for pull requests from forks (not from branches within wled/WLED)
if: github.event.pull_request.head.repo.full_name != github.repository
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
name: Gather Usermods
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install PlatformIO
run: pip install -r requirements.txt
- name: Get default environments
fetch-depth: 0
- name: Get changed usermod environments
id: envs
run: |
echo "usermods=$(find usermods/ -name library.json | xargs dirname | xargs -n 1 basename | jq -R | grep -v PWM_fan | grep -v BME68X_v2| grep -v pixels_dice_tray | jq --slurp -c)" >> $GITHUB_OUTPUT
# Usermods whose directories changed in this PR
changed=$(git diff --name-only ${{ github.event.pull_request.base.sha }} HEAD \
| grep '^usermods/' | cut -d/ -f2 | sort -u || true)
Comment on lines 27 to +30
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pass github.event.* values through env: instead of embedding them in the shell script.

Both scripts inject github.event.pull_request.base.sha directly into run:. The workflow guidelines explicitly forbid that pattern.

Suggested change
     - name: Get changed usermod environments
       id: envs
+      env:
+        PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
       run: |
         # Usermods whose directories changed in this PR
-        changed=$(git diff --name-only ${{ github.event.pull_request.base.sha }} HEAD \
+        changed=$(git diff --name-only "$PR_BASE_SHA" HEAD \
           | grep '^usermods/' | cut -d/ -f2 | sort -u || true)
     - name: Find usermods with custom build environments
       id: custom_envs
+      env:
+        PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
       run: |
         # On PRs: only scan usermods whose directories changed.
         # On push: scan all usermods (validates the full set on merge).
         if [ "${{ github.event_name }}" = "pull_request" ]; then
-          changed=$(git diff --name-only ${{ github.event.pull_request.base.sha }} HEAD \
+          changed=$(git diff --name-only "$PR_BASE_SHA" HEAD \
             | grep '^usermods/' | cut -d/ -f2 | sort -u || true)

As per coding guidelines, "Never interpolate github.event.* values directly into run: steps — pass them through an env: variable to prevent script injection."

Also applies to: 107-109

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/usermods.yml around lines 27 - 30, The run step injects
github.event.* values directly into the shell (the assignment to the changed
variable), which is forbidden; instead add env entries (e.g., BASE_SHA and any
other github.event.* used later) to the step and reference those env vars inside
the run script (use "$BASE_SHA" when computing changed), and repeat the same fix
for the other run step that currently interpolates github.event.* (the block
around where changed is computed again); ensure all github.event.* references
are passed via env: not embedded in run:.


# All usermods with a library.json (excluding known-incompatible ones)
all=$(find usermods/ -name library.json \
| xargs dirname | xargs -n 1 basename \
| grep -v PWM_fan | grep -v BME68X_v2 | grep -v pixels_dice_tray \
| sort || true)

if [ -z "$changed" ] || [ -z "$all" ]; then
echo "usermods=[]" >> $GITHUB_OUTPUT
else
usermods=$(comm -12 <(echo "$all") <(echo "$changed") | jq -R | jq --slurp -c)
echo "usermods=$usermods" >> $GITHUB_OUTPUT
fi
outputs:
usermods: ${{ steps.envs.outputs.usermods }}


build:
# Only run for pull requests from forks (not from branches within wled/WLED)
if: github.event.pull_request.head.repo.full_name != github.repository
# Skip when no changed usermods were found (e.g. only non-library changes)
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && needs.get_usermod_envs.outputs.usermods != '[]'
name: Build Enviornments
runs-on: ubuntu-latest
needs: get_usermod_envs
Expand Down Expand Up @@ -74,4 +89,85 @@ jobs:
cat platformio_override.ini

- name: Build firmware
run: pio run -e ${{ matrix.environment }}
run: pio run -e ${{ matrix.environment }}


get_custom_build_envs:
name: Gather Custom Build Environments
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Find usermods with custom build environments
id: custom_envs
run: |
# On PRs: only scan usermods whose directories changed.
# On push: scan all usermods (validates the full set on merge).
if [ "${{ github.event_name }}" = "pull_request" ]; then
changed=$(git diff --name-only ${{ github.event.pull_request.base.sha }} HEAD \
| grep '^usermods/' | cut -d/ -f2 | sort -u || true)
if [ -z "$changed" ]; then
echo "matrix=[]" >> $GITHUB_OUTPUT
exit 0
fi
samples=$(for mod in $changed; do
f="usermods/$mod/platformio_override.ini.sample"
[ -f "$f" ] && echo "$f"
done | sort)
else
samples=$(find usermods/ -name "platformio_override.ini.sample" | sort)
fi

result='[]'
for sample in $samples; do
usermod=$(dirname "$sample" | xargs basename)
# Skip usermods known to be incompatible (same list as get_usermod_envs)
case "$usermod" in PWM_fan|BME68X_v2|pixels_dice_tray) continue ;; esac
envs=$(grep -E '^\[env:[^]]+\]' "$sample" | sed 's/^\[env:\(.*\)\]$/\1/')
for env in $envs; do
result=$(echo "$result" | jq --arg u "$usermod" --arg e "$env" '. + [{usermod: $u, env: $e}]')
done
done
echo "matrix=$(echo "$result" | jq -c '.')" >> $GITHUB_OUTPUT
outputs:
matrix: ${{ steps.custom_envs.outputs.matrix }}


build_custom:
name: Build Custom Env (${{ matrix.usermod }} / ${{ matrix.env }})
runs-on: ubuntu-latest
needs: get_custom_build_envs
if: needs.get_custom_build_envs.outputs.matrix != '[]'
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.get_custom_build_envs.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm ci
- name: Cache PlatformIO
uses: actions/cache@v4
with:
path: |
~/.platformio/.cache
~/.buildcache
build_output
key: pio-${{ runner.os }}-${{ matrix.env }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-${{ hashFiles('wled00/**', 'usermods/**') }}
restore-keys: pio-${{ runner.os }}-${{ matrix.env }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install PlatformIO
run: pip install -r requirements.txt
- name: Apply custom build environment
run: cp -v "usermods/${{ matrix.usermod }}/platformio_override.ini.sample" platformio_override.ini
- name: Build firmware
run: pio run -e ${{ matrix.env }}
Comment on lines +95 to +173
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add an explicit permissions: block before expanding this workflow further.

These new jobs currently inherit the default GITHUB_TOKEN permissions. The repo workflow rules require least-privilege permissions to be declared explicitly.

Suggested change
+permissions:
+  contents: read
+
 jobs:

As per coding guidelines, "Declare explicit permissions: blocks scoped to least privilege."

🧰 Tools
🪛 zizmor (1.25.2)

[warning] 99-101: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 147-147: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 95-134: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 99-99: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 147-147: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 149-149: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 155-155: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 164-164: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/usermods.yml around lines 95 - 173, Add an explicit
permissions block (scoped to least privilege) to this workflow so jobs no longer
inherit default GITHUB_TOKEN rights; for example add a top-level or per-job
permissions: entry (before the job definitions or before the job
`get_custom_build_envs` / `build_custom`) declaring only required scopes such as
permissions: contents: read (and any other minimal scopes your jobs need) to
satisfy the repo rule requiring explicit least-privilege permissions.

31 changes: 2 additions & 29 deletions platformio_override.sample.ini
Original file line number Diff line number Diff line change
Expand Up @@ -509,42 +509,15 @@ lib_deps = ${esp8266.lib_deps}

# ------------------------------------------------------------------------------
# EleksTube-IPS
# See usermods/EleksTube_IPS/platformio_override.ini.sample
# ------------------------------------------------------------------------------
[env:elekstube_ips]
extends = esp32 ;; use default esp32 platform
board = esp32dev
upload_speed = 921600
custom_usermods = ${env:esp32dev.custom_usermods} RTC EleksTube_IPS
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_DISABLE_BROWNOUT_DET -D WLED_DISABLE_INFRARED
-D DATA_PINS=12
-D RLYPIN=27
-D BTNPIN=34
-D PIXEL_COUNTS=6
# Display config
-D ST7789_DRIVER
-D TFT_WIDTH=135
-D TFT_HEIGHT=240
-D CGRAM_OFFSET
-D TFT_SDA_READ
-D TFT_MOSI=23
-D TFT_SCLK=18
-D TFT_DC=25
-D TFT_RST=26
-D SPI_FREQUENCY=40000000
-D USER_SETUP_LOADED
monitor_filters = esp32_exception_decoder


# ------------------------------------------------------------------------------
# Usermod examples
# ------------------------------------------------------------------------------

# 433MHz RF remote example for esp32dev
[env:esp32dev_usermod_RF433]
extends = env:esp32dev
custom_usermods =
${env:esp32dev.custom_usermods}
RF433
# 433MHz RF remote example: see usermods/usermod_v2_RF433/platformio_override.ini.sample

# External usermod from a git repository.
# The library's `library.json` must include `"build": {"libArchive": false}`.
Expand Down
5 changes: 0 additions & 5 deletions usermods/AHT10_v2/platformio_override.ini

This file was deleted.

9 changes: 9 additions & 0 deletions usermods/AHT10_v2/platformio_override.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# AHT10/AHT15/AHT20 temperature/humidity usermod build environment
# Copy to platformio_override.ini in the WLED root to use.

[platformio]
default_envs = aht10_example

[env:aht10_example]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods} AHT10_v2
9 changes: 9 additions & 0 deletions usermods/BME280_v2/platformio_override.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# BME280_v2 usermod build environment
# Copy to platformio_override.ini in the WLED root to use.

[platformio]
default_envs = usermod_esp8266_2m

[env:usermod_esp8266_2m]
extends = env:esp8266_2m
custom_usermods = ${env:esp8266_2m.custom_usermods} BME280_v2
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
; USERMOD_DHT_MQTT - publish measurements to the MQTT broker
; USERMOD_DHT_STATS - For debug, report delay stats

[env:d1_mini_usermod_dht_C]
extends = env:d1_mini
custom_usermods = ${env:d1_mini.custom_usermods} DHT
build_flags = ${env:d1_mini.build_flags} -D USERMOD_DHT_CELSIUS
[env:esp8266_2m_usermod_dht_C]
extends = env:esp8266_2m
custom_usermods = ${env:esp8266_2m.custom_usermods} DHT
build_flags = ${env:esp8266_2m.build_flags} -D USERMOD_DHT_CELSIUS

[env:custom32_LEDPIN_16_usermod_dht_C]
extends = env:custom32_LEDPIN_16
custom_usermods = ${env:custom32_LEDPIN_16.custom_usermods} DHT
build_flags = ${env:custom32_LEDPIN_16.build_flags} -D USERMOD_DHT_CELSIUS -D USERMOD_DHT_STATS
[env:esp32dev_LEDPIN_16_usermod_dht_C]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods} DHT
build_flags = ${env:esp32dev.build_flags} -D LEDPIN=16 -D USERMOD_DHT_CELSIUS -D USERMOD_DHT_STATS

6 changes: 0 additions & 6 deletions usermods/INA226_v2/platformio_override.ini

This file was deleted.

23 changes: 23 additions & 0 deletions usermods/INA226_v2/platformio_override.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# INA226 power monitor usermod build environments
# Copy to platformio_override.ini in the WLED root to use.

[platformio]
default_envs = ina226_example

# Minimal example — enable the usermod with default settings
[env:ina226_example]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods} INA226_v2
build_flags = ${env:esp32dev.build_flags}
; -D USERMOD_INA226_DEBUG ; uncomment to add debug status to the info modal

# Custom calibration example — adjust constants to match your hardware
[env:ina226_custom]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods} INA226_v2
build_flags = ${env:esp32dev.build_flags}
-D INA226_ENABLED_DEFAULT=true
-D INA226_SHUNT_MICRO_OHMS=2888
-D INA226_DEFAULT_CURRENT_RANGE=10000
-D INA226_CURRENT_OFFSET_MA=-118
-D INA226_CHECK_INTERVAL_MS=1000
9 changes: 9 additions & 0 deletions usermods/LD2410_v2/platformio_override.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# LD2410 presence sensor usermod build environment
# Copy to platformio_override.ini in the WLED root to use.

[platformio]
default_envs = usermod_LD2410_v2_esp32dev

[env:usermod_LD2410_v2_esp32dev]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods} LD2410_v2
10 changes: 10 additions & 0 deletions usermods/LDR_Dusk_Dawn_v2/platformio_override.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# LDR Dusk/Dawn usermod build environment
# Copy to platformio_override.ini in the WLED root to use.

[platformio]
default_envs = usermod_LDR_Dusk_Dawn_esp32dev

[env:usermod_LDR_Dusk_Dawn_esp32dev]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods}
LDR_Dusk_Dawn
Comment on lines +7 to +10
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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
jq -r '.name' usermods/LDR_Dusk_Dawn_v2/library.json

Repository: wled/WLED

Length of output: 70


Fix custom_usermods to match the v2 usermod name (LDR_Dusk_Dawn_v2)
usermods/LDR_Dusk_Dawn_v2/library.json sets .name = LDR_Dusk_Dawn_v2, but usermods/LDR_Dusk_Dawn_v2/platformio_override.ini.sample currently uses LDR_Dusk_Dawn, so this env may not enable the intended usermod (lines 7-10).

[env:usermod_LDR_Dusk_Dawn_esp32dev]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods}
  LDR_Dusk_Dawn_v2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@usermods/LDR_Dusk_Dawn_v2/platformio_override.ini.sample` around lines 7 -
10, Update the custom_usermods entry in platformio_override.ini.sample so it
matches the usermod name declared in library.json: replace the currently listed
LDR_Dusk_Dawn with LDR_Dusk_Dawn_v2 under the env
[env:usermod_LDR_Dusk_Dawn_esp32dev] so custom_usermods includes the exact
symbol LDR_Dusk_Dawn_v2 (ensure the key custom_usermods remains intact and
preserves the existing ${env:esp32dev.custom_usermods} merge).

9 changes: 9 additions & 0 deletions usermods/MAX17048_v2/platformio_override.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# MAX17048 battery fuel gauge usermod build environment
# Copy to platformio_override.ini in the WLED root to use.

[platformio]
default_envs = usermod_max17048_esp8266_2m

[env:usermod_max17048_esp8266_2m]
extends = env:esp8266_2m
custom_usermods = ${env:esp8266_2m.custom_usermods} MAX17048_v2
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
; Options
; -------
; USERMOD_SN_PHOTORESISTOR - define this to have this user mod included wled00\usermods_list.cpp
; USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL - the number of milliseconds between measurements, defaults to 60 seconds
; USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT - the number of milliseconds after boot to take first measurement, defaults to 20 seconds
; USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE - the voltage supplied to the sensor, defaults to 5v
; USERMOD_SN_PHOTORESISTOR_ADC_PRECISION - the ADC precision is the number of distinguishable ADC inputs, defaults to 1024.0 (10 bits)
; USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE - the resistor size, defaults to 10000.0 (10K hms)
; USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE - the offset value to report on, defaults to 25
;
[env:usermod_sn_photoresistor_d1_mini]
extends = env:d1_mini
[env:usermod_sn_photoresistor_esp8266_2m]
extends = env:esp8266_2m
custom_usermods = ${env:esp8266_2m.custom_usermods} SN_Photoresistor
build_flags =
${common.build_flags_esp8266}
-D USERMOD_SN_PHOTORESISTOR
lib_deps = ${env.lib_deps}
${env:esp8266_2m.build_flags}
-D USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL=60
lib_deps = ${env:esp8266_2m.lib_deps}
8 changes: 0 additions & 8 deletions usermods/TTGO-T-Display/platformio_override.ini

This file was deleted.

16 changes: 16 additions & 0 deletions usermods/TTGO-T-Display/platformio_override.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; TTGO-T-Display usermod build example.
; Note: this usermod has no library.json so custom_usermods is not available.
; The usermod.cpp must be included manually in your build.

[platformio]
default_envs = ttgo_t_display_example

[env:ttgo_t_display_example]
extends = env:esp32dev
build_flags = ${env:esp32dev.build_flags}
; PIN defines - uncomment and change, if needed:
; -D LEDPIN=2
-D BTNPIN=35
; -D IRPIN=4
; -D RLYPIN=12
; -D RLYMDE=1
5 changes: 0 additions & 5 deletions usermods/Temperature/platformio_override.ini

This file was deleted.

10 changes: 10 additions & 0 deletions usermods/Temperature/platformio_override.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Temperature (DS18B20) usermod build environment
# Copy to platformio_override.ini in the WLED root to use.

[platformio]
default_envs = usermod_temperature_esp32dev

[env:usermod_temperature_esp32dev]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods}
Temperature
10 changes: 10 additions & 0 deletions usermods/mpu6050_imu/platformio_override.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# MPU-6050 IMU usermod build environment
# Copy to platformio_override.ini in the WLED root to use.

[platformio]
default_envs = usermod_mpu6050_imu_esp32dev

[env:usermod_mpu6050_imu_esp32dev]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods}
mpu6050_imu
Loading
Loading