4LineDisplay enhancements.
Boot loop (preset apply) fix.
This commit is contained in:
parent
a6feb77e52
commit
735205492e
@ -24,7 +24,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
class UsermodTemperature : public Usermod {
|
class UsermodTemperature : public Usermod {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool initDone = false;
|
||||||
OneWire *oneWire;
|
OneWire *oneWire;
|
||||||
DallasTemperature *sensor;
|
DallasTemperature *sensor;
|
||||||
// The device's unique 64-bit serial code stored in on-board ROM.
|
// The device's unique 64-bit serial code stored in on-board ROM.
|
||||||
@ -75,9 +78,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
|
||||||
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
|
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
|
||||||
if (!pinManager.allocatePin(temperaturePin,false)) {
|
if (!pinManager.allocatePin(temperaturePin,false)) {
|
||||||
temperaturePin = -1; // allocation failed
|
temperaturePin = -1; // allocation failed
|
||||||
@ -103,6 +104,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
} else {
|
} else {
|
||||||
DEBUG_PRINTLN(F("Dallas Temperature not found"));
|
DEBUG_PRINTLN(F("Dallas Temperature not found"));
|
||||||
}
|
}
|
||||||
|
initDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
@ -123,7 +125,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we were waiting for a conversion to complete, have we waited log enough?
|
// we were waiting for a conversion to complete, have we waited log enough?
|
||||||
if (now - lastTemperaturesRequest >= 94 /* 93.75ms per the datasheet */) {
|
if (now - lastTemperaturesRequest >= 95 /* 93.75ms per the datasheet */) {
|
||||||
getTemperature();
|
getTemperature();
|
||||||
|
|
||||||
if (WLED_MQTT_CONNECTED) {
|
if (WLED_MQTT_CONNECTED) {
|
||||||
@ -187,6 +189,7 @@ class UsermodTemperature : public Usermod {
|
|||||||
* Read "<usermodname>_<usermodparam>" from json state and and change settings (i.e. GPIO pin) used.
|
* Read "<usermodname>_<usermodparam>" from json state and and change settings (i.e. GPIO pin) used.
|
||||||
*/
|
*/
|
||||||
void readFromJsonState(JsonObject &root) {
|
void readFromJsonState(JsonObject &root) {
|
||||||
|
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||||
if (root[F("Temperature_pin")] != nullptr) {
|
if (root[F("Temperature_pin")] != nullptr) {
|
||||||
int8_t pin = (int)root[F("Temperature_pin")];
|
int8_t pin = (int)root[F("Temperature_pin")];
|
||||||
if (pin != temperaturePin) {
|
if (pin != temperaturePin) {
|
||||||
|
@ -57,8 +57,8 @@ typedef enum {
|
|||||||
FLD_LINE_3_BRIGHTNESS = 0,
|
FLD_LINE_3_BRIGHTNESS = 0,
|
||||||
FLD_LINE_3_EFFECT_SPEED,
|
FLD_LINE_3_EFFECT_SPEED,
|
||||||
FLD_LINE_3_EFFECT_INTENSITY,
|
FLD_LINE_3_EFFECT_INTENSITY,
|
||||||
FLD_LINE_3_PALETTE,
|
FLD_LINE_3_MODE,
|
||||||
FLD_LINE_3_TIME
|
FLD_LINE_3_PALETTE
|
||||||
} Line3Type;
|
} Line3Type;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -68,20 +68,23 @@ typedef enum {
|
|||||||
} DisplayType;
|
} DisplayType;
|
||||||
|
|
||||||
class FourLineDisplayUsermod : public Usermod {
|
class FourLineDisplayUsermod : public Usermod {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool initDone = false;
|
||||||
unsigned long lastTime = 0;
|
unsigned long lastTime = 0;
|
||||||
|
|
||||||
// HW interface & configuration
|
// HW interface & configuration
|
||||||
void *u8x8; // pointer to U8X8 display object
|
void *u8x8 = nullptr; // pointer to U8X8 display object
|
||||||
int8_t sclPin, sdaPin; // I2C pins for interfacing, get initialised in readFromConfig()
|
int8_t sclPin=FLD_PIN_SCL, sdaPin=FLD_PIN_SDA; // I2C pins for interfacing, get initialised in readFromConfig()
|
||||||
DisplayType type = NONE; // display type
|
DisplayType type = SSD1306; // display type
|
||||||
bool flip; // flip display 180°
|
bool flip = false; // flip display 180°
|
||||||
uint8_t contrast;
|
uint8_t contrast = 10; // screen contrast
|
||||||
uint8_t lineHeight; // 1 row or 2 rows
|
uint8_t lineHeight = 1; // 1 row or 2 rows
|
||||||
uint32_t refreshRate; // in ms
|
uint32_t refreshRate = USER_LOOP_REFRESH_RATE_MS; // in ms
|
||||||
uint32_t screenTimeout; // in ms
|
uint32_t screenTimeout = SCREEN_TIMEOUT_MS; // in ms
|
||||||
bool sleepMode; // allow screen sleep?
|
bool sleepMode = true; // allow screen sleep?
|
||||||
bool clockMode; // display clock instead of info?
|
bool clockMode = false; // display clock
|
||||||
|
|
||||||
// needRedraw marks if redraw is required to prevent often redrawing.
|
// needRedraw marks if redraw is required to prevent often redrawing.
|
||||||
bool needRedraw = true;
|
bool needRedraw = true;
|
||||||
@ -99,21 +102,19 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
uint8_t knownHour = 99;
|
uint8_t knownHour = 99;
|
||||||
|
|
||||||
bool displayTurnedOff = false;
|
bool displayTurnedOff = false;
|
||||||
long lastUpdate = 0;
|
unsigned long lastUpdate = 0;
|
||||||
long lastRedraw = 0;
|
unsigned long lastRedraw = 0;
|
||||||
long overlayUntil = 0;
|
unsigned long overlayUntil = 0;
|
||||||
Line3Type lineThreeType = FLD_LINE_3_BRIGHTNESS;
|
Line3Type lineThreeType = FLD_LINE_3_BRIGHTNESS;
|
||||||
// Set to 2 or 3 to mark lines 2 or 3. Other values ignored.
|
// Set to 2 or 3 to mark lines 2 or 3. Other values ignored.
|
||||||
byte markLineNum = 0;
|
byte markLineNum = 0;
|
||||||
|
|
||||||
char **modes_qstrings = nullptr;
|
|
||||||
char **palettes_qstrings = nullptr;
|
|
||||||
|
|
||||||
// If display does not work or looks corrupted check the
|
// If display does not work or looks corrupted check the
|
||||||
// constructor reference:
|
// constructor reference:
|
||||||
// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
|
// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
|
||||||
// or check the gallery:
|
// or check the gallery:
|
||||||
// https://github.com/olikraus/u8g2/wiki/gallery
|
// https://github.com/olikraus/u8g2/wiki/gallery
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// gets called once at boot. Do all initialization that doesn't depend on
|
// gets called once at boot. Do all initialization that doesn't depend on
|
||||||
@ -126,27 +127,22 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
case SSD1306:
|
case SSD1306:
|
||||||
u8x8 = (void *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA
|
u8x8 = (void *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA
|
||||||
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->begin();
|
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->begin();
|
||||||
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setFlipMode(flip);
|
|
||||||
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
|
|
||||||
break;
|
break;
|
||||||
case SH1106:
|
case SH1106:
|
||||||
u8x8 = (void *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA
|
u8x8 = (void *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, sclPin, sdaPin); // Pins are Reset, SCL, SDA
|
||||||
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->begin();
|
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->begin();
|
||||||
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->setFlipMode(flip);
|
|
||||||
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
u8x8 = nullptr;
|
u8x8 = nullptr;
|
||||||
type = NONE;
|
type = NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
setFlipMode(flip);
|
||||||
|
setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
|
||||||
setPowerSave(0);
|
setPowerSave(0);
|
||||||
String loading = String(F("Loading..."));
|
String loading = String(F("Loading..."));
|
||||||
drawString(0, 0, loading.c_str());
|
drawString(0, 0, loading.c_str());
|
||||||
|
initDone = true;
|
||||||
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
|
// gets called every time WiFi is (re-)connected. Initialize own network
|
||||||
@ -168,8 +164,31 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
/**
|
/**
|
||||||
* Wrappers for screen drawing
|
* Wrappers for screen drawing
|
||||||
*/
|
*/
|
||||||
|
void setFlipMode(uint8_t mode) {
|
||||||
|
switch (type) {
|
||||||
|
case SSD1306:
|
||||||
|
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setFlipMode(mode);
|
||||||
|
break;
|
||||||
|
case SH1106:
|
||||||
|
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->setFlipMode(mode);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void setContrast(uint8_t contrast) {
|
||||||
|
switch (type) {
|
||||||
|
case SSD1306:
|
||||||
|
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setContrast(contrast);
|
||||||
|
break;
|
||||||
|
case SH1106:
|
||||||
|
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->setContrast(contrast);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
void drawString(uint8_t col, uint8_t row, const char *string) {
|
void drawString(uint8_t col, uint8_t row, const char *string) {
|
||||||
if (type==NONE) return;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSD1306:
|
case SSD1306:
|
||||||
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setFont(u8x8_font_chroma48medium8_r);
|
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setFont(u8x8_font_chroma48medium8_r);
|
||||||
@ -181,10 +200,11 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
if (lineHeight==2) (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->draw1x2String(col, row, string);
|
if (lineHeight==2) (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->draw1x2String(col, row, string);
|
||||||
else (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->drawString(col, row, string);
|
else (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->drawString(col, row, string);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void draw2x2String(uint8_t col, uint8_t row, const char *string) {
|
void draw2x2String(uint8_t col, uint8_t row, const char *string) {
|
||||||
if (type==NONE) return;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSD1306:
|
case SSD1306:
|
||||||
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setFont(u8x8_font_chroma48medium8_r);
|
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setFont(u8x8_font_chroma48medium8_r);
|
||||||
@ -194,10 +214,11 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->setFont(u8x8_font_chroma48medium8_r);
|
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->setFont(u8x8_font_chroma48medium8_r);
|
||||||
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->draw2x2String(col, row, string);
|
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->draw2x2String(col, row, string);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font) {
|
void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font) {
|
||||||
if (type==NONE) return;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSD1306:
|
case SSD1306:
|
||||||
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setFont(font);
|
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setFont(font);
|
||||||
@ -209,19 +230,21 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
if (lineHeight==2) (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->draw1x2Glyph(col, row, glyph);
|
if (lineHeight==2) (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->draw1x2Glyph(col, row, glyph);
|
||||||
else (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->drawGlyph(col, row, glyph);
|
else (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->drawGlyph(col, row, glyph);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t getCols() {
|
uint8_t getCols() {
|
||||||
if (type==NONE) return 255;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSD1306:
|
case SSD1306:
|
||||||
return (static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->getCols();
|
return (static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->getCols();
|
||||||
case SH1106:
|
case SH1106:
|
||||||
return (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->getCols();
|
return (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->getCols();
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void clear() {
|
void clear() {
|
||||||
if (type==NONE) return;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSD1306:
|
case SSD1306:
|
||||||
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->clear();
|
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->clear();
|
||||||
@ -229,10 +252,11 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
case SH1106:
|
case SH1106:
|
||||||
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->clear();
|
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->clear();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void setPowerSave(uint8_t save) {
|
void setPowerSave(uint8_t save) {
|
||||||
if (type==NONE) return;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSD1306:
|
case SSD1306:
|
||||||
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setPowerSave(save);
|
(static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8))->setPowerSave(save);
|
||||||
@ -240,6 +264,8 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
case SH1106:
|
case SH1106:
|
||||||
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->setPowerSave(save);
|
(static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8))->setPowerSave(save);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,6 +313,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
if(sleepMode && !displayTurnedOff && (millis() - lastRedraw > screenTimeout)) {
|
if(sleepMode && !displayTurnedOff && (millis() - lastRedraw > screenTimeout)) {
|
||||||
// We will still check if there is a change in redraw()
|
// We will still check if there is a change in redraw()
|
||||||
// and turn it back on if it changed.
|
// and turn it back on if it changed.
|
||||||
|
knownHour = 99; // force screen clear
|
||||||
sleepOrClock(true);
|
sleepOrClock(true);
|
||||||
} else if (displayTurnedOff && clockMode) {
|
} else if (displayTurnedOff && clockMode) {
|
||||||
showTime();
|
showTime();
|
||||||
@ -294,26 +321,30 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
// change 4th line every 3s
|
// change 4th line every 3s
|
||||||
switch (lineThreeType) {
|
switch (lineThreeType) {
|
||||||
case FLD_LINE_3_BRIGHTNESS:
|
case FLD_LINE_3_BRIGHTNESS:
|
||||||
setLineThreeType(FLD_LINE_3_PALETTE);
|
setLineThreeType(FLD_LINE_3_EFFECT_SPEED);
|
||||||
|
break;
|
||||||
|
case FLD_LINE_3_MODE:
|
||||||
|
setLineThreeType(FLD_LINE_3_BRIGHTNESS);
|
||||||
break;
|
break;
|
||||||
case FLD_LINE_3_PALETTE:
|
case FLD_LINE_3_PALETTE:
|
||||||
setLineThreeType(FLD_LINE_3_EFFECT_SPEED);
|
setLineThreeType(clockMode ? FLD_LINE_3_MODE : FLD_LINE_3_BRIGHTNESS);
|
||||||
break;
|
break;
|
||||||
case FLD_LINE_3_EFFECT_SPEED:
|
case FLD_LINE_3_EFFECT_SPEED:
|
||||||
setLineThreeType(FLD_LINE_3_EFFECT_INTENSITY);
|
setLineThreeType(FLD_LINE_3_EFFECT_INTENSITY);
|
||||||
break;
|
break;
|
||||||
case FLD_LINE_3_EFFECT_INTENSITY:
|
case FLD_LINE_3_EFFECT_INTENSITY:
|
||||||
setLineThreeType(FLD_LINE_3_BRIGHTNESS);
|
setLineThreeType(FLD_LINE_3_PALETTE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setLineThreeType(FLD_LINE_3_BRIGHTNESS);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
drawLineThree();
|
drawLineFour();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else
|
} else {
|
||||||
|
knownHour = 99; // force time display
|
||||||
clear();
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
needRedraw = false;
|
needRedraw = false;
|
||||||
lastRedraw = millis();
|
lastRedraw = millis();
|
||||||
@ -354,11 +385,12 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
drawString(1, lineHeight, (knownIp.toString()).c_str());
|
drawString(1, lineHeight, (knownIp.toString()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Third row with mode name
|
// Third row with mode name or current time
|
||||||
showCurrentEffectOrPalette(modes_qstrings[knownMode], 2);
|
if (clockMode) showTime(false);
|
||||||
|
else showCurrentEffectOrPalette(knownMode, JSON_mode_names, 2);
|
||||||
|
|
||||||
// Fourth row
|
// Fourth row
|
||||||
drawLineThree();
|
drawLineFour();
|
||||||
|
|
||||||
drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0), u8x8_font_open_iconic_weather_2x2); // sun/moon icon
|
drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0), u8x8_font_open_iconic_weather_2x2); // sun/moon icon
|
||||||
drawGlyph(0, 0, 80, u8x8_font_open_iconic_embedded_1x1); // wifi icon
|
drawGlyph(0, 0, 80, u8x8_font_open_iconic_embedded_1x1); // wifi icon
|
||||||
@ -366,7 +398,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
//if (markLineNum>1) drawGlyph(2, markLineNum*lineHeight, 66, u8x8_font_open_iconic_arrow_1x1); // arrow icon
|
//if (markLineNum>1) drawGlyph(2, markLineNum*lineHeight, 66, u8x8_font_open_iconic_arrow_1x1); // arrow icon
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawLineThree() {
|
void drawLineFour() {
|
||||||
char lineBuffer[LINE_BUFFER_SIZE];
|
char lineBuffer[LINE_BUFFER_SIZE];
|
||||||
switch(lineThreeType) {
|
switch(lineThreeType) {
|
||||||
case FLD_LINE_3_BRIGHTNESS:
|
case FLD_LINE_3_BRIGHTNESS:
|
||||||
@ -381,9 +413,12 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
sprintf_P(lineBuffer, PSTR("FX Intens. %3d"), effectIntensity);
|
sprintf_P(lineBuffer, PSTR("FX Intens. %3d"), effectIntensity);
|
||||||
drawString(2, 3*lineHeight, lineBuffer);
|
drawString(2, 3*lineHeight, lineBuffer);
|
||||||
break;
|
break;
|
||||||
|
case FLD_LINE_3_MODE:
|
||||||
|
showCurrentEffectOrPalette(knownMode, JSON_mode_names, 3);
|
||||||
|
break;
|
||||||
case FLD_LINE_3_PALETTE:
|
case FLD_LINE_3_PALETTE:
|
||||||
default:
|
default:
|
||||||
showCurrentEffectOrPalette(palettes_qstrings[knownPalette], 3);
|
showCurrentEffectOrPalette(knownPalette, JSON_palette_names, 3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,23 +426,34 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
/**
|
/**
|
||||||
* Display the current effect or palette (desiredEntry)
|
* Display the current effect or palette (desiredEntry)
|
||||||
* on the appropriate line (row).
|
* on the appropriate line (row).
|
||||||
*
|
|
||||||
* TODO: Should we cache the current effect and
|
|
||||||
* TODO: palette name? This seems expensive.
|
|
||||||
*/
|
*/
|
||||||
void showCurrentEffectOrPalette(char *qstring, uint8_t row) {
|
void showCurrentEffectOrPalette(int knownMode, const char *qstring, uint8_t row) {
|
||||||
char lineBuffer[LINE_BUFFER_SIZE];
|
char lineBuffer[LINE_BUFFER_SIZE];
|
||||||
|
uint8_t qComma = 0;
|
||||||
|
bool insideQuotes = false;
|
||||||
uint8_t printedChars = 0;
|
uint8_t printedChars = 0;
|
||||||
char singleJsonSymbol;
|
char singleJsonSymbol;
|
||||||
while (printedChars < getCols() - 2) {
|
|
||||||
singleJsonSymbol = pgm_read_byte_near(qstring + printedChars);
|
// Find the mode name in JSON
|
||||||
if (singleJsonSymbol == '"' || singleJsonSymbol == '\0' ) {
|
for (size_t i = 0; i < strlen_P(qstring); i++) {
|
||||||
break;
|
singleJsonSymbol = pgm_read_byte_near(qstring + i);
|
||||||
|
if (singleJsonSymbol == '\0') break;
|
||||||
|
switch (singleJsonSymbol) {
|
||||||
|
case '"':
|
||||||
|
insideQuotes = !insideQuotes;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
qComma++;
|
||||||
|
default:
|
||||||
|
if (!insideQuotes || (qComma != knownMode)) break;
|
||||||
|
lineBuffer[printedChars++] = singleJsonSymbol;
|
||||||
}
|
}
|
||||||
lineBuffer[printedChars++] = singleJsonSymbol;
|
if ((qComma > knownMode) || (printedChars > getCols()-2) || printedChars > sizeof(lineBuffer)-2) break;
|
||||||
}
|
}
|
||||||
for (;printedChars<getCols()-2; printedChars++) lineBuffer[printedChars]=' ';
|
for (;printedChars < getCols()-2 || printedChars > sizeof(lineBuffer)-2; printedChars++) lineBuffer[printedChars]=' ';
|
||||||
lineBuffer[printedChars] = 0;
|
lineBuffer[printedChars] = 0;
|
||||||
drawString(2, row*lineHeight, lineBuffer);
|
drawString(2, row*lineHeight, lineBuffer);
|
||||||
}
|
}
|
||||||
@ -419,6 +465,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
* to wake up the screen.
|
* to wake up the screen.
|
||||||
*/
|
*/
|
||||||
bool wakeDisplay() {
|
bool wakeDisplay() {
|
||||||
|
knownHour = 99;
|
||||||
if (displayTurnedOff) {
|
if (displayTurnedOff) {
|
||||||
// Turn the display back on
|
// Turn the display back on
|
||||||
sleepOrClock(false);
|
sleepOrClock(false);
|
||||||
@ -454,8 +501,8 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
if (newLineThreeType == FLD_LINE_3_BRIGHTNESS ||
|
if (newLineThreeType == FLD_LINE_3_BRIGHTNESS ||
|
||||||
newLineThreeType == FLD_LINE_3_EFFECT_SPEED ||
|
newLineThreeType == FLD_LINE_3_EFFECT_SPEED ||
|
||||||
newLineThreeType == FLD_LINE_3_EFFECT_INTENSITY ||
|
newLineThreeType == FLD_LINE_3_EFFECT_INTENSITY ||
|
||||||
newLineThreeType == FLD_LINE_3_PALETTE ||
|
newLineThreeType == FLD_LINE_3_MODE ||
|
||||||
newLineThreeType == FLD_LINE_3_TIME) {
|
newLineThreeType == FLD_LINE_3_PALETTE) {
|
||||||
lineThreeType = newLineThreeType;
|
lineThreeType = newLineThreeType;
|
||||||
} else {
|
} else {
|
||||||
// Unknown value
|
// Unknown value
|
||||||
@ -483,18 +530,12 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
*/
|
*/
|
||||||
void sleepOrClock(bool enabled) {
|
void sleepOrClock(bool enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (clockMode) {
|
if (clockMode) showTime();
|
||||||
showTime();
|
else setPowerSave(1);
|
||||||
}
|
|
||||||
else {
|
|
||||||
setPowerSave(1);
|
|
||||||
}
|
|
||||||
displayTurnedOff = true;
|
displayTurnedOff = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!clockMode) {
|
setPowerSave(0);
|
||||||
setPowerSave(0);
|
|
||||||
}
|
|
||||||
displayTurnedOff = false;
|
displayTurnedOff = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -510,21 +551,22 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
updateLocalTime();
|
updateLocalTime();
|
||||||
byte minuteCurrent = minute(localTime);
|
byte minuteCurrent = minute(localTime);
|
||||||
byte hourCurrent = hour(localTime);
|
byte hourCurrent = hour(localTime);
|
||||||
|
byte secondCurrent = second(localTime);
|
||||||
if (knownMinute == minuteCurrent && knownHour == hourCurrent) {
|
if (knownMinute == minuteCurrent && knownHour == hourCurrent) {
|
||||||
// Time hasn't changed.
|
// Time hasn't changed.
|
||||||
return;
|
if (!fullScreen) return;
|
||||||
|
} else {
|
||||||
|
if (fullScreen) clear();
|
||||||
}
|
}
|
||||||
knownMinute = minuteCurrent;
|
knownMinute = minuteCurrent;
|
||||||
knownHour = hourCurrent;
|
knownHour = hourCurrent;
|
||||||
|
|
||||||
if (fullScreen) clear();
|
|
||||||
|
|
||||||
int currentMonth = month(localTime);
|
int currentMonth = month(localTime);
|
||||||
sprintf_P(lineBuffer, PSTR("%s %2d "), monthShortStr(currentMonth), day(localTime));
|
sprintf_P(lineBuffer, PSTR("%s %2d "), monthShortStr(currentMonth), day(localTime));
|
||||||
if (fullScreen)
|
if (fullScreen)
|
||||||
draw2x2String(DATE_INDENT, lineHeight==1 ? 0 : lineHeight, lineBuffer);
|
draw2x2String(DATE_INDENT, lineHeight==1 ? 0 : lineHeight, lineBuffer);
|
||||||
else
|
else
|
||||||
drawString(0, lineHeight, lineBuffer);
|
drawString(2, lineHeight*2, lineBuffer);
|
||||||
|
|
||||||
byte showHour = hourCurrent;
|
byte showHour = hourCurrent;
|
||||||
boolean isAM = false;
|
boolean isAM = false;
|
||||||
@ -542,13 +584,17 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf_P(lineBuffer, PSTR("%02d:%02d %s"), showHour, minuteCurrent, useAMPM ? (isAM ? "AM" : "PM") : "");
|
sprintf_P(lineBuffer, PSTR("%2d:%02d"), (useAMPM && fullScreen ? showHour : hourCurrent), minuteCurrent);
|
||||||
// For time, we always use LINE_HEIGHT of 2 since
|
// For time, we always use LINE_HEIGHT of 2 since
|
||||||
// we are printing it big.
|
// we are printing it big.
|
||||||
if (fullScreen)
|
if (fullScreen) {
|
||||||
draw2x2String(TIME_INDENT + (useAMPM ? 0 : 2), lineHeight*2, lineBuffer);
|
draw2x2String(TIME_INDENT+2, lineHeight*2, lineBuffer);
|
||||||
else
|
if (useAMPM) drawString(12, lineHeight*2, (isAM ? "AM" : "PM"));
|
||||||
drawString(8, lineHeight, lineBuffer);
|
sprintf_P(lineBuffer, PSTR("%02d"), secondCurrent);
|
||||||
|
drawString(12, lineHeight*2+1, lineBuffer);
|
||||||
|
} else {
|
||||||
|
drawString(9, lineHeight*2, lineBuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -575,34 +621,48 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
* Values in the state object may be modified by connected clients
|
* Values in the state object may be modified by connected clients
|
||||||
*/
|
*/
|
||||||
void readFromJsonState(JsonObject& root) {
|
void readFromJsonState(JsonObject& root) {
|
||||||
|
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||||
DisplayType newType = type;
|
DisplayType newType = type;
|
||||||
uint8_t newScl = sclPin;
|
uint8_t newScl = sclPin;
|
||||||
uint8_t newSda = sdaPin;
|
uint8_t newSda = sdaPin;
|
||||||
uint8_t newContrast = contrast;
|
|
||||||
bool newFlip = flip;
|
|
||||||
|
|
||||||
if (root[F("4LineDisplay_type")] != nullptr) newType = (DisplayType)root[F("4LineDisplay_type")];
|
// just to reduce memory
|
||||||
if (root[F("4LineDisplay_pin")] != nullptr) {
|
String str4LineDisplay_type = String(F("4LineDisplay_type"));
|
||||||
newScl = (int)root[F("4LineDisplay_pin")][0];
|
String str4LineDisplay_pin = String(F("4LineDisplay_pin"));
|
||||||
newSda = (int)root[F("4LineDisplay_pin")][1];
|
String str4LineDisplay_contrast = String(F("4LineDisplay_contrast"));
|
||||||
|
String str4LineDisplay_refreshRate = String(F("4LineDisplay_refreshRate"));
|
||||||
|
String str4LineDisplay_screenTimeOut = String(F("4LineDisplay_screenTimeOut"));
|
||||||
|
String str4LineDisplay_flip = String(F("4LineDisplay_flip"));
|
||||||
|
String str4LineDisplay_sleepMode = String(F("4LineDisplay_sleepMode"));
|
||||||
|
String str4LineDisplay_clockMode = String(F("4LineDisplay_clockMode"));
|
||||||
|
|
||||||
|
if (root[str4LineDisplay_type] != nullptr) newType = (DisplayType)root[str4LineDisplay_type];
|
||||||
|
if (root[str4LineDisplay_pin] != nullptr) {
|
||||||
|
newScl = (int)root[str4LineDisplay_pin][0];
|
||||||
|
newSda = (int)root[str4LineDisplay_pin][1];
|
||||||
}
|
}
|
||||||
if (root[F("4LineDisplay_contrast")] != nullptr) newContrast = (int)root[F("4LineDisplay_contrast")];
|
if (root[str4LineDisplay_contrast] != nullptr) {
|
||||||
if (root[F("4LineDisplay_refreshRate")] != nullptr) refreshRate = (int)root[F("4LineDisplay_refreshRate")]*1000;
|
contrast = (int)root[str4LineDisplay_contrast];
|
||||||
if (root[F("4LineDisplay_screenTimeOut")] != nullptr) screenTimeout = (int)root[F("4LineDisplay_screenTimeOut")]*1000;
|
setContrast(contrast);
|
||||||
if (root[F("4LineDisplay_flip")] != nullptr) {
|
|
||||||
String str = root[F("4LineDisplay_flip")]; // checkbox -> off or on
|
|
||||||
newFlip = (bool)(str!="off"); // off is guaranteed to be present
|
|
||||||
}
|
}
|
||||||
if (root[F("4LineDisplay_sleepMode")] != nullptr) {
|
if (root[str4LineDisplay_refreshRate] != nullptr) refreshRate = (int)root[str4LineDisplay_refreshRate]*1000;
|
||||||
String str = root[F("4LineDisplay_sleepMode")]; // checkbox -> off or on
|
if (root[str4LineDisplay_screenTimeOut] != nullptr) screenTimeout = (int)root[str4LineDisplay_screenTimeOut]*1000;
|
||||||
|
if (root[str4LineDisplay_flip] != nullptr) {
|
||||||
|
String str = root[str4LineDisplay_flip]; // checkbox -> off or on
|
||||||
|
flip = (bool)(str!="off"); // off is guaranteed to be present
|
||||||
|
setFlipMode(flip);
|
||||||
|
}
|
||||||
|
if (root[str4LineDisplay_sleepMode] != nullptr) {
|
||||||
|
String str = root[str4LineDisplay_sleepMode]; // checkbox -> off or on
|
||||||
sleepMode = (bool)(str!="off"); // off is guaranteed to be present
|
sleepMode = (bool)(str!="off"); // off is guaranteed to be present
|
||||||
}
|
}
|
||||||
if (root[F("4LineDisplay_clockMode")] != nullptr) {
|
if (root[str4LineDisplay_clockMode] != nullptr) {
|
||||||
String str = root[F("4LineDisplay_clockMode")]; // checkbox -> off or on
|
String str = root[str4LineDisplay_clockMode]; // checkbox -> off or on
|
||||||
clockMode = (bool)(str!="off"); // off is guaranteed to be present
|
clockMode = (bool)(str!="off"); // off is guaranteed to be present
|
||||||
|
setLineThreeType(clockMode ? FLD_LINE_3_MODE : FLD_LINE_3_BRIGHTNESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flip!=newFlip || contrast!=newContrast || sclPin!=newScl || sdaPin!=newSda || type!=newType) {
|
if (sclPin!=newScl || sdaPin!=newSda || type!=newType) {
|
||||||
if (type==SSD1306) delete (static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8));
|
if (type==SSD1306) delete (static_cast<U8X8_SSD1306_128X32_UNIVISION_HW_I2C*>(u8x8));
|
||||||
if (type==SH1106) delete (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8));
|
if (type==SH1106) delete (static_cast<U8X8_SH1106_128X64_WINSTAR_HW_I2C*>(u8x8));
|
||||||
pinManager.deallocatePin(sclPin);
|
pinManager.deallocatePin(sclPin);
|
||||||
@ -610,11 +670,10 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
sclPin = newScl;
|
sclPin = newScl;
|
||||||
sdaPin = newSda;
|
sdaPin = newSda;
|
||||||
type = newType;
|
type = newType;
|
||||||
contrast = newContrast;
|
|
||||||
flip = newFlip;
|
|
||||||
lineHeight = type==SH1106 ? 2 : 1;
|
lineHeight = type==SH1106 ? 2 : 1;
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
|
if (!wakeDisplay()) redraw(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -655,16 +714,20 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
*/
|
*/
|
||||||
void readFromConfig(JsonObject& root) {
|
void readFromConfig(JsonObject& root) {
|
||||||
JsonObject top = root[F("4LineDisplay")];
|
JsonObject top = root[F("4LineDisplay")];
|
||||||
sclPin = top["pin"][0] | FLD_PIN_SCL;
|
if (!top.isNull() && top["pin"] != nullptr) {
|
||||||
sdaPin = top["pin"][1] | FLD_PIN_SDA;
|
sclPin = top["pin"][0] | FLD_PIN_SCL;
|
||||||
type = top["type"] | SSD1306;
|
sdaPin = top["pin"][1] | FLD_PIN_SDA;
|
||||||
lineHeight = type==SH1106 ? 2 : 1;
|
type = top["type"] | SSD1306;
|
||||||
flip = top[F("flip")] | false ;
|
lineHeight = type==SH1106 ? 2 : 1;
|
||||||
contrast = top[F("contrast")] | 10;
|
flip = top[F("flip")] | false ;
|
||||||
refreshRate = int(top[F("refreshRate")])*1000 | USER_LOOP_REFRESH_RATE_MS;
|
contrast = top[F("contrast")] | 10;
|
||||||
screenTimeout = int(top[F("screenTimeOut")])*1000 | SCREEN_TIMEOUT_MS;
|
refreshRate = int(top[F("refreshRate")])*1000 | USER_LOOP_REFRESH_RATE_MS;
|
||||||
sleepMode = top[F("sleepMode")] | true;
|
screenTimeout = int(top[F("screenTimeOut")])*1000 | SCREEN_TIMEOUT_MS;
|
||||||
clockMode = top[F("clockMode")] | false;
|
sleepMode = top[F("sleepMode")] | true;
|
||||||
|
clockMode = top[F("clockMode")] | false;
|
||||||
|
} else {
|
||||||
|
DEBUG_PRINTLN(F("No config found. (Using defaults.)"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -674,5 +737,4 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
uint16_t getId() {
|
uint16_t getId() {
|
||||||
return USERMOD_ID_FOUR_LINE_DISP;
|
return USERMOD_ID_FOUR_LINE_DISP;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user