Merge pull request #1771 from Aircoookie/mergedev_210222

Update dev
This commit is contained in:
Aircoookie 2021-02-22 22:31:22 +01:00 committed by GitHub
commit 06f2f9adbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 369 additions and 2958 deletions

2887
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ default_envs = travis_esp8266, travis_esp32
; default_envs = d1_mini_5CH_Shojo_PCB
; default_envs = wemos_shield_esp32
; default_envs = m5atom
; default_envs = esp32_poe
; default_envs = esp32_eth
src_dir = ./wled00
data_dir = ./wled00/data
@ -279,12 +279,12 @@ lib_ignore =
ESPAsyncTCP
ESPAsyncUDP
[env:esp32_poe]
[env:esp32_eth]
board = esp32-poe
platform = espressif32@2.0
upload_speed = 921600
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
build_flags = ${common.build_flags_esp32} -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
lib_ignore =
ESPAsyncTCP
ESPAsyncUDP

View File

@ -11,7 +11,7 @@ default_envs = WLED_tasmota_1M
board = esp01_1m
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m0m}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266}
; *********************************************************************

View File

@ -10,7 +10,10 @@
// OLED displays to provide a four line display
// for WLED.
//
// This Usermod works best, by far, when coupled with RotaryEncoderUIUsermod.
// Dependencies
// * This usermod REQURES the ModeSortUsermod
// * This Usermod works best, by far, when coupled
// with RotaryEncoderUIUsermod.
//
// Make sure to enable NTP and set your time zone in WLED Config | Time.
//
@ -124,6 +127,9 @@ class FourLineDisplayUsermod : public Usermod {
char lineBuffer[LINE_BUFFER_SIZE];
char **modes_qstrings = nullptr;
char **palettes_qstrings = nullptr;
// If display does not work or looks corrupted check the
// constructor reference:
// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
@ -140,6 +146,10 @@ class FourLineDisplayUsermod : public Usermod {
u8x8.setContrast(10); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.DRAW_STRING(0, 0*LINE_HEIGHT, "Loading...");
ModeSortUsermod *modeSortUsermod = (ModeSortUsermod*) usermods.lookup(USERMOD_ID_MODE_SORT);
modes_qstrings = modeSortUsermod->getModesQStrings();
palettes_qstrings = modeSortUsermod->getPalettesQStrings();
}
// gets called every time WiFi is (re-)connected. Initialize own network
@ -254,7 +264,7 @@ class FourLineDisplayUsermod : public Usermod {
}
// Third row with mode name
showCurrentEffectOrPalette(JSON_mode_names, 2, knownMode);
showCurrentEffectOrPalette(modes_qstrings[knownMode], 2);
switch(lineThreeType) {
case FLD_LINE_3_BRIGHTNESS:
@ -270,7 +280,7 @@ class FourLineDisplayUsermod : public Usermod {
u8x8.DRAW_STRING(1, 3*LINE_HEIGHT, lineBuffer);
break;
case FLD_LINE_3_PALETTE:
showCurrentEffectOrPalette(JSON_palette_names, 3, knownPalette);
showCurrentEffectOrPalette(palettes_qstrings[knownPalette], 3);
break;
}
@ -289,35 +299,21 @@ class FourLineDisplayUsermod : public Usermod {
* TODO: Should we cache the current effect and
* TODO: palette name? This seems expensive.
*/
void showCurrentEffectOrPalette(const char json[], uint8_t row, uint8_t desiredEntry) {
uint8_t qComma = 0;
bool insideQuotes = false;
// advance past the mark for markLineNum that may exist.
void showCurrentEffectOrPalette(char *qstring, uint8_t row) {
uint8_t printedChars = 1;
char singleJsonSymbol;
// Find the mode name in JSON
for (size_t i = 0; i < strlen_P(json); i++) {
singleJsonSymbol = pgm_read_byte_near(json + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != desiredEntry)) {
break;
}
u8x8.DRAW_GLYPH(printedChars, row * LINE_HEIGHT, singleJsonSymbol);
printedChars++;
}
if ((qComma > desiredEntry) || (printedChars > u8x8.getCols() - 2)) {
int i = 0;
while (true) {
singleJsonSymbol = pgm_read_byte_near(qstring + i);
if (singleJsonSymbol == '"' || singleJsonSymbol == '\0' ) {
break;
}
u8x8.DRAW_GLYPH(printedChars, row * LINE_HEIGHT, singleJsonSymbol);
printedChars++;
if ( (printedChars > u8x8.getCols() - 2)) {
break;
}
i++;
}
}

View File

@ -0,0 +1,33 @@
# Mode Sort
v2 usermod that provides data about modes and
palettes to other usermods. Notably it provides:
* A direct method for a mode or palette name
* Ability to retrieve mode and palette names in
alphabetical order
```char **getModesQStrings()```
Provides an array of char* (pointers) to the names of the
palettes within JSON_mode_names, in the same order as
JSON_mode_names. These strings end in double quote (")
(or \0 if there is a problem).
```byte *getModesAlphaIndexes()```
An array of byte designating the indexes of names of the
modes in alphabetical order. "Solid" will always remain
at the front of the list.
```char **getPalettesQStrings()```
Provides an array of char* (pointers) to the names of the
palettes within JSON_palette_names, in the same order as
JSON_palette_names. These strings end in double quote (")
(or \0 if there is a problem).
```byte *getPalettesAlphaIndexes()```
An array of byte designating the indexes of names of the
palettes in alphabetical order. "Default" and those
starting with "(" will always remain at the front of the list.

View File

@ -0,0 +1,248 @@
#pragma once
#include "wled.h"
//
// v2 usermod that provides data about modes and
// palettes to other usermods. Notably it provides:
// * A direct method for a mode or palette name
// * Ability to retrieve mode and palette names in
// alphabetical order
//
// char **getModesQStrings()
// Provides an array of char* (pointers) to the names of the
// palettes within JSON_mode_names, in the same order as
// JSON_mode_names. These strings end in double quote (")
// (or \0 if there is a problem).
//
// byte *getModesAlphaIndexes()
// An array of byte designating the indexes of names of the
// modes in alphabetical order. "Solid" will always remain
// at the front of the list.
//
// char **getPalettesQStrings()
// Provides an array of char* (pointers) to the names of the
// palettes within JSON_palette_names, in the same order as
// JSON_palette_names. These strings end in double quote (")
// (or \0 if there is a problem).
//
// byte *getPalettesAlphaIndexes()
// An array of byte designating the indexes of names of the
// palettes in alphabetical order. "Default" and those
// starting with "(" will always remain at the front of the list.
//
// Number of modes at the start of the list to not sort
#define MODE_SORT_SKIP_COUNT 1
// Which list is being sorted
char **listBeingSorted = nullptr;
/**
* Modes and palettes are stored as strings that
* end in a quote character. Compare two of them.
* We are comparing directly within either
* JSON_mode_names or JSON_palette_names.
*/
int re_qstringCmp(const void *ap, const void *bp) {
char *a = listBeingSorted[*((byte *)ap)];
char *b = listBeingSorted[*((byte *)bp)];
int i = 0;
do {
char aVal = pgm_read_byte_near(a + i);
if (aVal >= 97 && aVal <= 122) {
// Lowercase
aVal -= 32;
}
char bVal = pgm_read_byte_near(b + i);
if (bVal >= 97 && bVal <= 122) {
// Lowercase
bVal -= 32;
}
// Relly we shouldn't ever get to '\0'
if (aVal == '"' || bVal == '"' || aVal == '\0' || bVal == '\0') {
// We're done. one is a substring of the other
// or something happenend and the quote didn't stop us.
if (aVal == bVal) {
// Same value, probably shouldn't happen
// with this dataset
return 0;
}
else if (aVal == '"' || aVal == '\0') {
return -1;
}
else {
return 1;
}
}
if (aVal == bVal) {
// Same characters. Move to the next.
i++;
continue;
}
// We're done
if (aVal < bVal) {
return -1;
}
else {
return 1;
}
} while (true);
// We shouldn't get here.
return 0;
}
class ModeSortUsermod : public Usermod {
private:
// Pointers the start of the mode names within JSON_mode_names
char **modes_qstrings = nullptr;
// Array of mode indexes in alphabetical order.
byte *modes_alpha_indexes = nullptr;
// Pointers the start of the palette names within JSON_palette_names
char **palettes_qstrings = nullptr;
// Array of palette indexes in alphabetical order.
byte *palettes_alpha_indexes = nullptr;
public:
/**
* setup() is called once at boot. WiFi is not yet connected at this point.
* You can use it to initialize variables, sensors or similar.
*/
void setup() {
// Sort the modes and palettes on startup
// as they are guarantted to change.
sortModesAndPalettes();
}
char **getModesQStrings() {
return modes_qstrings;
}
byte *getModesAlphaIndexes() {
return modes_alpha_indexes;
}
char **getPalettesQStrings() {
return palettes_qstrings;
}
byte *getPalettesAlphaIndexes() {
return palettes_alpha_indexes;
}
/**
* This Usermod doesn't have anything for loop.
*/
void loop() {}
/**
* Sort the modes and palettes to the index arrays
* modes_alpha_indexes and palettes_alpha_indexes.
*/
void sortModesAndPalettes() {
modes_qstrings = re_findModeStrings(JSON_mode_names, strip.getModeCount());
modes_alpha_indexes = re_initIndexArray(strip.getModeCount());
re_sortModes(modes_qstrings, modes_alpha_indexes, strip.getModeCount(), MODE_SORT_SKIP_COUNT);
palettes_qstrings = re_findModeStrings(JSON_palette_names, strip.getPaletteCount());
palettes_alpha_indexes = re_initIndexArray(strip.getPaletteCount());
int skipPaletteCount = 1;
while (true) {
// How many palette names start with '*' and should not be sorted?
// (Also skipping the first one, 'Default').
if (pgm_read_byte_near(palettes_qstrings[skipPaletteCount]) == '*') {
skipPaletteCount++;
}
else {
break;
}
}
re_sortModes(palettes_qstrings, palettes_alpha_indexes, strip.getPaletteCount(), skipPaletteCount);
}
byte *re_initIndexArray(int numModes) {
byte *indexes = (byte *)malloc(sizeof(byte) * numModes);
for (byte i = 0; i < numModes; i++) {
indexes[i] = i;
}
return indexes;
}
/**
* Return an array of mode or palette names from the JSON string.
* They don't end in '\0', they end in '"'.
*/
char **re_findModeStrings(const char json[], int numModes) {
char **modeStrings = (char **)malloc(sizeof(char *) * numModes);
uint8_t modeIndex = 0;
bool insideQuotes = false;
// advance past the mark for markLineNum that may exist.
char singleJsonSymbol;
// Find the mode name in JSON
bool complete = false;
for (size_t i = 0; i < strlen_P(json); i++) {
singleJsonSymbol = pgm_read_byte_near(json + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
if (insideQuotes) {
// We have a new mode or palette
modeStrings[modeIndex] = (char *)(json + i + 1);
}
break;
case '[':
break;
case ']':
complete = true;
break;
case ',':
modeIndex++;
default:
if (!insideQuotes) {
break;
}
}
if (complete) {
break;
}
}
return modeStrings;
}
/**
* Sort either the modes or the palettes using quicksort.
*/
void re_sortModes(char **modeNames, byte *indexes, int count, int numSkip) {
listBeingSorted = modeNames;
qsort(indexes + numSkip, count - numSkip, sizeof(byte), re_qstringCmp);
listBeingSorted = nullptr;
}
/*
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void addToJsonState(JsonObject &root) {}
/*
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void readFromJsonState(JsonObject &root) {}
/*
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
* This could be used in the future for the system to determine whether your usermod is installed.
*/
uint16_t getId()
{
return USERMOD_ID_MODE_SORT;
}
};

View File

@ -8,6 +8,7 @@ platform = espressif32@2.0
build_unflags = ${common.build_unflags}
build_flags =
${common.build_flags_esp32}
-D USERMOD_MODE_SORT
-D USERMOD_FOUR_LINE_DISLAY -D FLD_PIN_SCL=22 -D FLD_PIN_SDA=21
-D USERMOD_ROTARY_ENCODER_UI -D ENCODER_DT_PIN=18 -D ENCODER_CLK_PIN=5 -D ENCODER_SW_PIN=19
-D USERMOD_AUTO_SAVE -D AUTOSAVE_PRESET_NUM=1
@ -26,6 +27,7 @@ board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags =
${common.build_flags_esp8266}
-D USERMOD_MODE_SORT
-D USERMOD_FOUR_LINE_DISLAY -D FLD_PIN_SCL=5 -D FLD_PIN_SDA=4
-D USERMOD_ROTARY_ENCODER_UI -D ENCODER_DT_PIN=12 -D ENCODER_CLK_PIN=14 -D ENCODER_SW_PIN=13
-D USERMOD_AUTO_SAVE -D AUTOSAVE_PRESET_NUM=1

View File

@ -9,8 +9,6 @@
//
// v2 usermod that provides a rotary encoder-based UI.
//
// This Usermod works best coupled with FourLineDisplayUsermod.
//
// This usermod allows you to control:
//
// * Brightness
@ -21,6 +19,11 @@
//
// Change between modes by pressing a button.
//
// Dependencies
// * This usermod REQURES the ModeSortUsermod
// * This Usermod works best coupled with
// FourLineDisplayUsermod.
//
#ifndef ENCODER_DT_PIN
#define ENCODER_DT_PIN 12
@ -42,36 +45,10 @@
#define FLD_LINE_3_PALETTE 0
#endif
// The last UI state
#define LAST_UI_STATE 4
/**
* Array of mode indexes in alphabetical order.
* Should be ordered from JSON_mode_names array in FX.h.
*
* NOTE: If JSON_mode_names changes, this will need to be updated.
*/
const byte modes_alpha_order[] = {
0, 27, 38, 115, 1, 26, 91, 68, 2, 88, 102, 114, 28, 31, 32,
30, 29, 111, 52, 34, 8, 74, 67, 112, 18, 19, 96, 7, 117, 12,
69, 66, 45, 42, 90, 89, 110, 87, 46, 53, 82, 100, 58, 64, 75,
41, 57, 47, 44, 76, 77, 59, 70, 71, 72, 73, 107, 62, 101, 65,
98, 105, 109, 97, 48, 49, 95, 63, 78, 43, 9, 33, 5, 79, 99,
15, 37, 16, 10, 11, 40, 60, 108, 92, 93, 94, 103, 83, 84, 20,
21, 22, 85, 86, 39, 61, 23, 25, 24, 104, 6, 36, 13, 14, 35,
54, 56, 55, 116, 17, 81, 80, 106, 51, 50, 113, 3, 4 };
/**
* Array of palette indexes in alphabetical order.
* Should be ordered from JSON_palette_names array in FX.h.
*
* NOTE: If JSON_palette_names changes, this will need to be updated.
*/
const byte palettes_alpha_order[] = {
0, 1, 2, 3, 4, 5, 18, 46, 51, 50, 55, 39, 26, 22, 15,
48, 52, 53, 7, 37, 24, 30, 35, 10, 32, 28, 29, 36, 31,
25, 8, 38, 40, 41, 9, 44, 47, 6, 20, 11, 12, 16, 33,
14, 49, 27, 19, 13, 21, 54, 34, 45, 23, 43, 17, 42 };
class RotaryEncoderUIUsermod : public Usermod {
private:
@ -86,10 +63,14 @@ private:
unsigned char prev_button_state = HIGH;
#ifdef USERMOD_FOUR_LINE_DISLAY
FourLineDisplayUsermod* display;
FourLineDisplayUsermod *display;
#else
void* display = nullptr;
#endif
byte *modes_alpha_indexes = nullptr;
byte *palettes_alpha_indexes = nullptr;
unsigned char Enc_A;
unsigned char Enc_B;
unsigned char Enc_A_prev = 0;
@ -111,6 +92,10 @@ public:
currentTime = millis();
loopTime = currentTime;
ModeSortUsermod *modeSortUsermod = (ModeSortUsermod*) usermods.lookup(USERMOD_ID_MODE_SORT);
modes_alpha_indexes = modeSortUsermod->getModesAlphaIndexes();
palettes_alpha_indexes = modeSortUsermod->getPalettesAlphaIndexes();
#ifdef USERMOD_FOUR_LINE_DISLAY
// This Usermod uses FourLineDisplayUsermod for the best experience.
// But it's optional. But you want it.
@ -246,16 +231,16 @@ public:
void findCurrentEffectAndPalette() {
currentEffectAndPaleeteInitialized = true;
for (uint8_t i = 0; i < strip.getModeCount(); i++) {
byte value = modes_alpha_order[i];
if (modes_alpha_order[i] == effectCurrent) {
byte value = modes_alpha_indexes[i];
if (modes_alpha_indexes[i] == effectCurrent) {
effectCurrentIndex = i;
break;
}
}
for (uint8_t i = 0; i < strip.getPaletteCount(); i++) {
byte value = palettes_alpha_order[i];
if (palettes_alpha_order[i] == strip.getSegment(0).palette) {
byte value = palettes_alpha_indexes[i];
if (palettes_alpha_indexes[i] == strip.getSegment(0).palette) {
effectPaletteIndex = i;
break;
}
@ -315,7 +300,7 @@ public:
else {
effectCurrentIndex = (effectCurrentIndex - 1 < 0) ? (strip.getModeCount() - 1) : (effectCurrentIndex - 1);
}
effectCurrent = modes_alpha_order[effectCurrentIndex];
effectCurrent = modes_alpha_indexes[effectCurrentIndex];
lampUdated();
}
@ -364,7 +349,7 @@ public:
else {
effectPaletteIndex = (effectPaletteIndex - 1 < 0) ? (strip.getPaletteCount() - 1) : (effectPaletteIndex - 1);
}
effectPalette = palettes_alpha_order[effectPaletteIndex];
effectPalette = palettes_alpha_indexes[effectPaletteIndex];
lampUdated();
}
@ -380,7 +365,6 @@ public:
//this code adds "u":{"Light":[20," lux"]} to the info object
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
JsonArray lightArr = user.createNestedArray("Light"); //name
lightArr.add(reading); //value
lightArr.add(" lux"); //unit
@ -414,7 +398,4 @@ public:
{
return USERMOD_ID_ROTARY_ENC_UI;
}
//More methods can be added in the future, this example will then be extended.
//Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class!
};

View File

@ -31,6 +31,7 @@
#define USERMOD_ID_ROTARY_ENC_UI 8 //Usermod "usermod_v2_rotary_encoder_ui.h"
#define USERMOD_ID_AUTO_SAVE 9 //Usermod "usermod_v2_auto_save.h"
#define USERMOD_ID_DHT 10 //Usermod "usermod_dht.h"
#define USERMOD_ID_MODE_SORT 11 //Usermod "usermod_v2_mode_sort.h"
//Access point behavior
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
@ -140,6 +141,7 @@
#define WLED_ETH_NONE 0
#define WLED_ETH_WT32_ETH01 1
#define WLED_ETH_ESP32_POE 2
#define WLED_ETH_WESP32 3
//Hue error codes
#define HUE_ERROR_INACTIVE 0

View File

@ -69,7 +69,8 @@
<select name="ETH">
<option value="0">None</option>
<option value="1">WT32-ETH01</option>
<option value="2">ESP32-POE</option></select><br><br></div>
<option value="2">ESP32-POE</option>
<option value="3">WESP32</option></select><br><br></div>
<hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button>
</form>

View File

@ -64,8 +64,9 @@ Can help with connectivity issues.<br>
Do not enable if WiFi is working correctly, increases power consumption.</i><div
id="ethd"><h3>Ethernet Type</h3><select name="ETH"><option value="0">None
</option><option value="1">WT32-ETH01</option><option value="2">ESP32-POE
</option></select><br><br></div><hr><button type="button" onclick="B()">Back
</button><button type="submit">Save & Connect</button></form></body></html>)=====";
</option><option value="3">WESP32</option></select><br><br></div><hr><button
type="button" onclick="B()">Back</button><button type="submit">Save & Connect
</button></form></body></html>)=====";
// Autogenerated from wled00/data/settings_leds.htm, do not edit!!

View File

@ -23,6 +23,9 @@
#include "usermod_v2_SensorsToMqtt.h"
#endif
#ifdef USERMOD_MODE_SORT
#include "../usermods/usermod_v2_mode_sort/usermod_v2_mode_sort.h"
#endif
// BME280 v2 usermod. Define "USERMOD_BME280" in my_config.h
#ifdef USERMOD_BME280
@ -67,6 +70,10 @@ void registerUsermods()
#ifdef USERMOD_SENSORSTOMQTT
usermods.add(new UserMod_SensorsToMQTT());
#endif
#ifdef USERMOD_MODE_SORT
usermods.add(new ModeSortUsermod());
#endif
#ifdef USERMOD_FOUR_LINE_DISLAY
usermods.add(new FourLineDisplayUsermod());
#endif
@ -76,7 +83,8 @@ void registerUsermods()
#ifdef USERMOD_AUTO_SAVE
usermods.add(new AutoSaveUsermod());
#endif
#ifdef USERMOD_DHT
usermods.add(new UsermodDHT());
#endif
}
}

View File

@ -48,6 +48,16 @@ ethernet_settings ethernetBoards[] = {
18, // eth_mdio,
ETH_PHY_LAN8720, // eth_type,
ETH_CLOCK_GPIO17_OUT // eth_clk_mode
},
// WESP32
{
0, // eth_address,
-1, // eth_power,
16, // eth_mdc,
17, // eth_mdio,
ETH_PHY_LAN8720, // eth_type,
ETH_CLOCK_GPIO0_IN // eth_clk_mode
}
};

View File

@ -223,7 +223,11 @@ WLED_GLOBAL IPAddress staticGateway _INIT_N((( 0, 0, 0, 0))); // gateway (r
WLED_GLOBAL IPAddress staticSubnet _INIT_N(((255, 255, 255, 0))); // most common subnet in home networks
WLED_GLOBAL bool noWifiSleep _INIT(false); // disabling modem sleep modes will increase heat output and power usage, but may help with connection issues
#ifdef WLED_USE_ETHERNET
WLED_GLOBAL int ethernetType _INIT(WLED_ETH_ESP32_POE); // ethernet board type
#ifdef WLED_ETH_DEFAULT // default ethernet board type if specified
WLED_GLOBAL int ethernetType _INIT(WLED_ETH_DEFAULT); // ethernet board type
#else
WLED_GLOBAL int ethernetType _INIT(WLED_ETH_NONE); // use none for ethernet board type if default not defined
#endif
#endif
// LED CONFIG