Skip to content

Commit ab883a3

Browse files
authored
Merge branch 'wled:main' into main
2 parents 22ef6c8 + 66869f8 commit ab883a3

28 files changed

+676
-383
lines changed

.github/workflows/pr-merge.yaml

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,33 @@
11
name: Notify Discord on PR Merge
22
on:
3+
workflow_dispatch:
34
pull_request:
45
types: [closed]
56

67
jobs:
78
notify:
89
runs-on: ubuntu-latest
910
steps:
10-
- name: Send Discord notification
11-
shell: bash
11+
- name: Get User Permission
12+
id: checkAccess
13+
uses: actions-cool/check-user-permission@v2
14+
with:
15+
require: write
16+
username: ${{ github.triggering_actor }}
1217
env:
13-
DISCORD_WEBHOOK_BETA_TESTERS: ${{ secrets.DISCORD_WEBHOOK_BETA_TESTERS }}
14-
if: github.event.pull_request.merged == true
18+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19+
- name: Check User Permission
20+
if: steps.checkAccess.outputs.require-result == 'false'
21+
run: |
22+
echo "${{ github.triggering_actor }} does not have permissions on this repo."
23+
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
24+
echo "Job originally triggered by ${{ github.actor }}"
25+
exit 1
26+
- name: Checkout code
27+
uses: actions/checkout@v3
28+
with:
29+
ref: ${{ github.event.pull_request.head.sha }} # This is dangerous without the first access check
30+
- name: Send Discord notification
31+
# if: github.event.pull_request.merged == true
1532
run: |
16-
curl -H "Content-Type: application/json" -d '{"content": "Pull Request #{{ github.event.pull_request.number }} merged by {{ github.actor }}"}' $DISCORD_WEBHOOK_BETA_TESTERS
33+
curl -H "Content-Type: application/json" -d '{"content": "Pull Request ${{ github.event.pull_request.number }} merged by ${{ github.actor }}"}' ${{ secrets.DISCORD_WEBHOOK_BETA_TESTERS }}

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pio-scripts/load_usermods.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,18 @@ def wrapped_ConfigureProjectLibBuilder(xenv):
7777
for dep in result.depbuilders:
7878
cached_add_includes(dep, processed_deps, extra_include_dirs)
7979

80+
wled_deps = [dep for dep in result.depbuilders if is_wled_module(dep)]
81+
8082
broken_usermods = []
81-
for dep in result.depbuilders:
82-
if is_wled_module(dep):
83-
# Add the wled folder to the include path
84-
dep.env.PrependUnique(CPPPATH=str(wled_dir))
85-
# Add WLED's own dependencies
86-
for dir in extra_include_dirs:
87-
dep.env.PrependUnique(CPPPATH=str(dir))
88-
# Enforce that libArchive is not set; we must link them directly to the executable
89-
if dep.lib_archive:
90-
broken_usermods.append(dep)
83+
for dep in wled_deps:
84+
# Add the wled folder to the include path
85+
dep.env.PrependUnique(CPPPATH=str(wled_dir))
86+
# Add WLED's own dependencies
87+
for dir in extra_include_dirs:
88+
dep.env.PrependUnique(CPPPATH=str(dir))
89+
# Enforce that libArchive is not set; we must link them directly to the executable
90+
if dep.lib_archive:
91+
broken_usermods.append(dep)
9192

9293
if broken_usermods:
9394
broken_usermods = [usermod.name for usermod in broken_usermods]
@@ -97,6 +98,9 @@ def wrapped_ConfigureProjectLibBuilder(xenv):
9798
err=True)
9899
Exit(1)
99100

101+
# Save the depbuilders list for later validation
102+
xenv.Replace(WLED_MODULES=wled_deps)
103+
100104
return result
101105

102106
# Apply the wrapper

pio-scripts/validate_modules.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,8 @@ def validate_map_file(source, target, env):
5353
secho(f"ERROR: Map file not found: {map_file_path}", fg="red", err=True)
5454
Exit(1)
5555

56-
# Identify the WLED module source directories
57-
module_lib_builders = [builder for builder in env.GetLibBuilders() if is_wled_module(env, builder)]
58-
59-
if env.GetProjectOption("custom_usermods","") == "*":
60-
# All usermods build; filter non-platform-OK modules
61-
module_lib_builders = [builder for builder in module_lib_builders if env.IsCompatibleLibBuilder(builder)]
62-
else:
63-
incompatible_builders = [builder for builder in module_lib_builders if not env.IsCompatibleLibBuilder(builder)]
64-
if incompatible_builders:
65-
secho(
66-
f"ERROR: Modules {[b.name for b in incompatible_builders]} are not compatible with this platform!",
67-
fg="red",
68-
err=True)
69-
Exit(1)
56+
# Identify the WLED module builders, set by load_usermods.py
57+
module_lib_builders = env['WLED_MODULES']
7058

7159
# Extract the values we care about
7260
modules = {Path(builder.build_dir).name: builder.name for builder in module_lib_builders}

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pyelftools==0.32
3838
# via platformio
3939
pyserial==3.5
4040
# via platformio
41-
requests==2.32.3
41+
requests==2.32.4
4242
# via platformio
4343
semantic-version==2.10.0
4444
# via platformio
@@ -50,7 +50,7 @@ tabulate==0.9.0
5050
# via platformio
5151
typing-extensions==4.12.2
5252
# via anyio
53-
urllib3==2.3.0
53+
urllib3==2.5.0
5454
# via requests
5555
uvicorn==0.34.0
5656
# via platformio

usermods/audioreactive/audio_reactive.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,14 @@ static bool udpSyncConnected = false; // UDP connection status -> true i
6565

6666
// audioreactive variables
6767
#ifdef ARDUINO_ARCH_ESP32
68+
#ifndef SR_AGC // Automatic gain control mode
69+
#define SR_AGC 0 // default mode = off
70+
#endif
6871
static float micDataReal = 0.0f; // MicIn data with full 24bit resolution - lowest 8bit after decimal point
6972
static float multAgc = 1.0f; // sample * multAgc = sampleAgc. Our AGC multiplier
7073
static float sampleAvg = 0.0f; // Smoothed Average sample - sampleAvg < 1 means "quiet" (simple noise gate)
7174
static float sampleAgc = 0.0f; // Smoothed AGC sample
72-
static uint8_t soundAgc = 0; // Automagic gain control: 0 - none, 1 - normal, 2 - vivid, 3 - lazy (config value)
75+
static uint8_t soundAgc = SR_AGC; // Automatic gain control: 0 - off, 1 - normal, 2 - vivid, 3 - lazy (config value)
7376
#endif
7477
//static float volumeSmth = 0.0f; // either sampleAvg or sampleAgc depending on soundAgc; smoothed sample
7578
static float FFT_MajorPeak = 1.0f; // FFT: strongest (peak) frequency

usermods/audioreactive/readme.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ You can use the following additional flags in your `build_flags`
6060

6161
* `-D SR_SQUELCH=x` : Default "squelch" setting (10)
6262
* `-D SR_GAIN=x` : Default "gain" setting (60)
63+
* `-D SR_AGC=x` : (Only ESP32) Default "AGC (Automatic Gain Control)" setting (0): 0=off, 1=normal, 2=vivid, 3=lazy
6364
* `-D I2S_USE_RIGHT_CHANNEL`: Use RIGHT instead of LEFT channel (not recommended unless you strictly need this).
64-
* `-D I2S_USE_16BIT_SAMPLES`: Use 16bit instead of 32bit for internal sample buffers. Reduces sampling quality, but frees some RAM ressources (not recommended unless you absolutely need this).
65+
* `-D I2S_USE_16BIT_SAMPLES`: Use 16bit instead of 32bit for internal sample buffers. Reduces sampling quality, but frees some RAM resources (not recommended unless you absolutely need this).
6566
* `-D I2S_GRAB_ADC1_COMPLETELY`: Experimental: continuously sample analog ADC microphone. Only effective on ESP32. WARNING this *will* cause conflicts(lock-up) with any analogRead() call.
6667
* `-D MIC_LOGGER` : (debugging) Logs samples from the microphone to serial USB. Use with serial plotter (Arduino IDE)
6768
* `-D SR_DEBUG` : (debugging) Additional error diagnostics and debug info on serial USB.

usermods/user_fx/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Usermod user FX
2+
3+
This Usermod is a common place to put various user's LED effects.
4+

usermods/user_fx/library.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "user_fx",
3+
"build": { "libArchive": false }
4+
}

usermods/user_fx/user_fx.cpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#include "wled.h"
2+
3+
// for information how FX metadata strings work see https://kno.wled.ge/interfaces/json-api/#effect-metadata
4+
5+
// static effect, used if an effect fails to initialize
6+
static uint16_t mode_static(void) {
7+
SEGMENT.fill(SEGCOLOR(0));
8+
return strip.isOffRefreshRequired() ? FRAMETIME : 350;
9+
}
10+
11+
/////////////////////////
12+
// User FX functions //
13+
/////////////////////////
14+
15+
// Diffusion Fire: fire effect intended for 2D setups smaller than 16x16
16+
static uint16_t mode_diffusionfire(void) {
17+
if (!strip.isMatrix || !SEGMENT.is2D())
18+
return mode_static(); // not a 2D set-up
19+
20+
const int cols = SEG_W;
21+
const int rows = SEG_H;
22+
const auto XY = [&](int x, int y) { return x + y * cols; };
23+
24+
const uint8_t refresh_hz = map(SEGMENT.speed, 0, 255, 20, 80);
25+
const unsigned refresh_ms = 1000 / refresh_hz;
26+
const int16_t diffusion = map(SEGMENT.custom1, 0, 255, 0, 100);
27+
const uint8_t spark_rate = SEGMENT.intensity;
28+
const uint8_t turbulence = SEGMENT.custom2;
29+
30+
unsigned dataSize = SEGMENT.length(); // allocate persistent data for heat value for each pixel
31+
if (!SEGENV.allocateData(dataSize))
32+
return mode_static(); // allocation failed
33+
34+
if (SEGENV.call == 0) {
35+
SEGMENT.fill(BLACK);
36+
SEGENV.step = 0;
37+
}
38+
39+
if ((strip.now - SEGENV.step) >= refresh_ms) {
40+
uint8_t tmp_row[cols];
41+
SEGENV.step = strip.now;
42+
// scroll up
43+
for (unsigned y = 1; y < rows; y++)
44+
for (unsigned x = 0; x < cols; x++) {
45+
unsigned src = XY(x, y);
46+
unsigned dst = XY(x, y - 1);
47+
SEGMENT.data[dst] = SEGMENT.data[src];
48+
}
49+
50+
if (hw_random8() > turbulence) {
51+
// create new sparks at bottom row
52+
for (unsigned x = 0; x < cols; x++) {
53+
uint8_t p = hw_random8();
54+
if (p < spark_rate) {
55+
unsigned dst = XY(x, rows - 1);
56+
SEGMENT.data[dst] = 255;
57+
}
58+
}
59+
}
60+
61+
// diffuse
62+
for (unsigned y = 0; y < rows; y++) {
63+
for (unsigned x = 0; x < cols; x++) {
64+
unsigned v = SEGMENT.data[XY(x, y)];
65+
if (x > 0) {
66+
v += SEGMENT.data[XY(x - 1, y)];
67+
}
68+
if (x < (cols - 1)) {
69+
v += SEGMENT.data[XY(x + 1, y)];
70+
}
71+
tmp_row[x] = min(255, (int)(v * 100 / (300 + diffusion)));
72+
}
73+
74+
for (unsigned x = 0; x < cols; x++) {
75+
SEGMENT.data[XY(x, y)] = tmp_row[x];
76+
if (SEGMENT.check1) {
77+
uint32_t color = ColorFromPalette(SEGPALETTE, tmp_row[x], 255, LINEARBLEND_NOWRAP);
78+
SEGMENT.setPixelColorXY(x, y, color);
79+
} else {
80+
uint32_t color = SEGCOLOR(0);
81+
SEGMENT.setPixelColorXY(x, y, color_fade(color, tmp_row[x]));
82+
}
83+
}
84+
}
85+
}
86+
return FRAMETIME;
87+
}
88+
static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spark rate,Diffusion Speed,Turbulence,,Use palette;;Color;;2;pal=35";
89+
90+
91+
/////////////////////
92+
// UserMod Class //
93+
/////////////////////
94+
95+
class UserFxUsermod : public Usermod {
96+
private:
97+
public:
98+
void setup() override {
99+
strip.addEffect(255, &mode_diffusionfire, _data_FX_MODE_DIFFUSIONFIRE);
100+
101+
////////////////////////////////////////
102+
// add your effect function(s) here //
103+
////////////////////////////////////////
104+
105+
// use id=255 for all custom user FX (the final id is assigned when adding the effect)
106+
107+
// strip.addEffect(255, &mode_your_effect, _data_FX_MODE_YOUR_EFFECT);
108+
// strip.addEffect(255, &mode_your_effect2, _data_FX_MODE_YOUR_EFFECT2);
109+
// strip.addEffect(255, &mode_your_effect3, _data_FX_MODE_YOUR_EFFECT3);
110+
}
111+
void loop() override {} // nothing to do in the loop
112+
uint16_t getId() override { return USERMOD_ID_USER_FX; }
113+
};
114+
115+
static UserFxUsermod user_fx;
116+
REGISTER_USERMOD(user_fx);

0 commit comments

Comments
 (0)