Skip to content

Commit 8e71c3a

Browse files
kdorffKevin Dorff
andauthored
Rotary Encoder, Four Line Display, and Auto Save Usermods (wled#1722)
* Ability to lookup Usermod by id so Usermods can use other Usermods. * Rotary Encoder UI using two Usermods * Updates. More to come, probably. * Updated rotary usermod to honor USE_FOUR_LINE_DISPLAY if you want to use four line display. It should be truly optional, now. * minor logic improvement to showing the current time in clock mode. * improved 24 hour display foratting and ability to use the FourLineDisplayUsermod without the RotaryEncoderUIUsermod (option disable sleep and clock modes). * Improved ordering of defines in the FourLineDisplayUsermod to put options people might need to change together toward the top. * relocate plugins. add mention of the Wire requirement. * usermod filenames changed, updating comment in const.h * fix usermod locations. * fix usermods_list to include changed folder. * Improved for both usermods: install, config, and docs. Included sample platform_override.ini. * Updated name of SDA and SCL defines for config of display * update docs. * Wrong year. Fixed. * Fix youtube link, improve config of sleep/clock when the rotary usermod isn't installed. * Minor fixes to four line display. Addition of Auto Save v2 usermod. * Allow config for auto-save to set the preset number to use. Load preset at startup (so brightness is set correctly). * Updated docs for Auto Save. * Updated docs for Auto Save. Co-authored-by: Kevin Dorff <[email protected]>
1 parent 94941a7 commit 8e71c3a

File tree

11 files changed

+1341
-0
lines changed

11 files changed

+1341
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Auto Save
2+
3+
v2 Usermod to automatically save settings
4+
to preset number AUTOSAVE_PRESET_NUM after a change to any of
5+
6+
* brightness
7+
* effect speed
8+
* effect intensity
9+
* mode (effect)
10+
* palette
11+
12+
but it will wait for AUTOSAVE_SETTLE_MS milliseconds, a "settle"
13+
period in case there are other changes (any change will
14+
extend the "settle" window).
15+
16+
It will additionally load preset AUTOSAVE_PRESET_NUM at startup.
17+
during the first `loop()`. Reasoning below.
18+
19+
AutoSaveUsermod is standalone, but if FourLineDisplayUsermod is installed, it will notify the user of the saved changes.
20+
21+
Note: I don't love that WLED doesn't respect the brightness of the preset being auto loaded, so the AutoSaveUsermod will set the AUTOSAVE_PRESET_NUM preset in the first loop, so brightness IS honored. This means WLED will effectively ignore Default brightness and Apply N preset at boot when the AutoSaveUsermod is installed.
22+
23+
## Installation
24+
25+
Copy and update the example `platformio_override.ini.sample`
26+
from the Rotary Encoder UI usermode folder to the root directory of your particular build.
27+
This file should be placed in the same directory as `platformio.ini`.
28+
29+
### Define Your Options
30+
31+
* `USERMOD_AUTO_SAVE` - define this to have this the Auto Save usermod included wled00\usermods_list.cpp
32+
* `USERMOD_FOUR_LINE_DISLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp - also tells this usermod that the display is available (see the Four Line Display usermod `readme.md` for more details)
33+
* `AUTOSAVE_SETTLE_MS` - Minimum time to wave before auto saving, defaults to 10000 (10s)
34+
* `AUTOSAVE_PRESET_NUM` - Preset number to auto-save to, auto-load at startup from, defaults to 99
35+
36+
### PlatformIO requirements
37+
38+
No special requirements.
39+
40+
Note: the Four Line Display usermod requires the libraries `U8g2` and `Wire`.
41+
42+
## Change Log
43+
44+
2021-02
45+
* First public release
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
#pragma once
2+
3+
#include "wled.h"
4+
5+
//
6+
// v2 Usermod to automatically save settings
7+
// to preset number AUTOSAVE_PRESET_NUM after a change to any of
8+
//
9+
// * brightness
10+
// * effect speed
11+
// * effect intensity
12+
// * mode (effect)
13+
// * palette
14+
//
15+
// but it will wait for AUTOSAVE_SETTLE_MS milliseconds, a "settle"
16+
// period in case there are other changes (any change will
17+
// extend the "settle" window).
18+
//
19+
// It will additionally load preset AUTOSAVE_PRESET_NUM at startup.
20+
// during the first `loop()`. Reasoning below.
21+
//
22+
// AutoSaveUsermod is standalone, but if FourLineDisplayUsermod
23+
// is installed, it will notify the user of the saved changes.
24+
//
25+
// Note: I don't love that WLED doesn't respect the brightness
26+
// of the preset being auto loaded, so the AutoSaveUsermod
27+
// will set the AUTOSAVE_PRESET_NUM preset in the first loop,
28+
// so brightness IS honored. This means WLED will effectively
29+
// ignore Default brightness and Apply N preset at boot when
30+
// the AutoSaveUsermod is installed.
31+
32+
//How long to wait after settings change to auto-save
33+
#ifndef AUTOSAVE_SETTLE_MS
34+
#define AUTOSAVE_SETTLE_MS 10*1000
35+
#endif
36+
37+
//Preset number to save to
38+
#ifndef AUTOSAVE_PRESET_NUM
39+
#define AUTOSAVE_PRESET_NUM 99
40+
#endif
41+
42+
// "Auto save MM-DD HH:MM:SS"
43+
#define PRESET_NAME_BUFFER_SIZE 25
44+
45+
class AutoSaveUsermod : public Usermod {
46+
private:
47+
// If we've detected the need to auto save, this will
48+
// be non zero.
49+
unsigned long autoSaveAfter = 0;
50+
51+
char presetNameBuffer[PRESET_NAME_BUFFER_SIZE];
52+
53+
bool firstLoop = true;
54+
55+
uint8_t knownBrightness = 0;
56+
uint8_t knownEffectSpeed = 0;
57+
uint8_t knownEffectIntensity = 0;
58+
uint8_t knownMode = 0;
59+
uint8_t knownPalette = 0;
60+
61+
#ifdef USERMOD_FOUR_LINE_DISLAY
62+
FourLineDisplayUsermod* display;
63+
#endif
64+
65+
public:
66+
// gets called once at boot. Do all initialization that doesn't depend on
67+
// network here
68+
void setup() {
69+
#ifdef USERMOD_FOUR_LINE_DISLAY
70+
// This Usermod has enhanced funcionality if
71+
// FourLineDisplayUsermod is available.
72+
display = (FourLineDisplayUsermod*) usermods.lookup(USERMOD_ID_FOUR_LINE_DISP);
73+
#endif
74+
}
75+
76+
// gets called every time WiFi is (re-)connected. Initialize own network
77+
// interfaces here
78+
void connected() {}
79+
80+
/**
81+
* Da loop.
82+
*/
83+
void loop() {
84+
unsigned long now = millis();
85+
uint8_t currentMode = strip.getMode();
86+
uint8_t currentPalette = strip.getSegment(0).palette;
87+
if (firstLoop) {
88+
firstLoop = false;
89+
applyPreset(AUTOSAVE_PRESET_NUM);
90+
knownBrightness = bri;
91+
knownEffectSpeed = effectSpeed;
92+
knownEffectIntensity = effectIntensity;
93+
knownMode = currentMode;
94+
knownPalette = currentPalette;
95+
return;
96+
}
97+
98+
unsigned long wouldAutoSaveAfter = now + AUTOSAVE_SETTLE_MS;
99+
if (knownBrightness != bri) {
100+
knownBrightness = bri;
101+
autoSaveAfter = wouldAutoSaveAfter;
102+
} else if (knownEffectSpeed != effectSpeed) {
103+
knownEffectSpeed = effectSpeed;
104+
autoSaveAfter = wouldAutoSaveAfter;
105+
} else if (knownEffectIntensity != effectIntensity) {
106+
knownEffectIntensity = effectIntensity;
107+
autoSaveAfter = wouldAutoSaveAfter;
108+
} else if (knownMode != currentMode) {
109+
knownMode = currentMode;
110+
autoSaveAfter = wouldAutoSaveAfter;
111+
} else if (knownPalette != currentPalette) {
112+
knownPalette = currentPalette;
113+
autoSaveAfter = wouldAutoSaveAfter;
114+
}
115+
116+
if (autoSaveAfter && now > autoSaveAfter) {
117+
autoSaveAfter = 0;
118+
// Time to auto save. You may have some flickry?
119+
saveSettings();
120+
displayOverlay();
121+
}
122+
}
123+
124+
void saveSettings() {
125+
updateLocalTime();
126+
sprintf(presetNameBuffer,
127+
"Auto save %02d-%02d %02d:%02d:%02d",
128+
month(localTime), day(localTime),
129+
hour(localTime), minute(localTime), second(localTime));
130+
savePreset(AUTOSAVE_PRESET_NUM, true, presetNameBuffer);
131+
}
132+
133+
void displayOverlay() {
134+
#ifdef USERMOD_FOUR_LINE_DISLAY
135+
if (display != nullptr) {
136+
display->wakeDisplay();
137+
display->overlay("Settings", "Auto Saved", 1500);
138+
}
139+
#endif
140+
}
141+
142+
/*
143+
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
144+
* Values in the state object may be modified by connected clients
145+
*/
146+
void addToJsonState(JsonObject& root) {
147+
}
148+
149+
/*
150+
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
151+
* Values in the state object may be modified by connected clients
152+
*/
153+
void readFromJsonState(JsonObject& root) {
154+
}
155+
156+
/*
157+
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
158+
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
159+
* If you want to force saving the current state, use serializeConfig() in your loop().
160+
*
161+
* CAUTION: serializeConfig() will initiate a filesystem write operation.
162+
* It might cause the LEDs to stutter and will cause flash wear if called too often.
163+
* Use it sparingly and always in the loop, never in network callbacks!
164+
*
165+
* addToConfig() will also not yet add your setting to one of the settings pages automatically.
166+
* To make that work you still have to add the setting to the HTML, xml.cpp and set.cpp manually.
167+
*
168+
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
169+
*/
170+
void addToConfig(JsonObject& root) {
171+
}
172+
173+
/*
174+
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
175+
* This is called by WLED when settings are loaded (currently this only happens once immediately after boot)
176+
*
177+
* readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
178+
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
179+
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
180+
*/
181+
void readFromConfig(JsonObject& root) {
182+
}
183+
184+
/*
185+
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
186+
* This could be used in the future for the system to determine whether your usermod is installed.
187+
*/
188+
uint16_t getId() {
189+
return USERMOD_ID_AUTO_SAVE;
190+
}
191+
192+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Rotary Encoder UI Usermod
2+
3+
First, thanks to the authors of the ssd11306_i2c_oled_u8g2 mod.
4+
5+
This usermod provides a four line display using either
6+
128x32 or 128x64 OLED displays.
7+
It's can operate independently, but starts to provide
8+
a relatively complete on-device UI when paired with the
9+
Rotary Encoder UI usermod. I strongly encourage you to use
10+
them together.
11+
12+
[See the pair of usermods in action](https://www.youtube.com/watch?v=tITQY80rIOA)
13+
14+
## Installation
15+
16+
Copy and update the example `platformio_override.ini.sample`
17+
from the Rotary Encoder UI usermode folder to the root directory of your particular build.
18+
This file should be placed in the same directory as `platformio.ini`.
19+
20+
### Define Your Options
21+
22+
* `USERMOD_FOUR_LINE_DISLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp - also tells Rotary Encoder usermod, if installed, that the display is available
23+
* `FLD_PIN_SCL` - The display SCL pin, defaults to 5
24+
* `FLD_PIN_SDA` - The display SDA pin, defaults to 4
25+
* `FLIP_MODE` - Set to 0 or 1
26+
* `LINE_HEIGHT` - Set to 1 or 2
27+
28+
There are other `#define` values in the Usermod that might be of interest.
29+
30+
### PlatformIO requirements
31+
32+
This usermod requires the `U8g2` and `Wire` libraries. See the
33+
`platformio_override.ini.sample` found in the Rotary Encoder
34+
UI usermod folder for how to include these using `platformio_override.ini`.
35+
36+
## Change Log
37+
38+
2021-02
39+
* First public release

0 commit comments

Comments
 (0)