Tidied animation for wifi activity and mode indications when no traffic

This commit is contained in:
Ray Jones 2019-06-02 19:19:08 +10:00
parent 0a6171ae8b
commit 200b928af6
10 changed files with 245 additions and 224 deletions

View file

@ -119,7 +119,7 @@
const int FirmwareRevision = 23;
const int FirmwareSubRevision = 0;
const char* FirmwareDate = "21 May 2019";
const char* FirmwareDate = "1 Jun 2019";
#ifdef ESP32
@ -143,6 +143,7 @@ bool validateFrame(const CProtocol& frame, const char* name);
void checkDisplayUpdate();
void checkDebugCommands();
void manageCyclicMode();
void doStreaming();
// DS18B20 temperature sensor support
OneWire ds(15); // on pin 5 (a 4.7K resistor is necessary)
@ -325,6 +326,8 @@ void setup() {
BoardRevision = BoardDetect();
DebugPort.printf("Board revision: V%.1f\r\n", float(BoardRevision) * 0.1);
DebugPort.printf("ESP32 IDF Version: %s\r\n", esp_get_idf_version());
#if USE_SPIFFS == 1
// Initialize SPIFFS
if(!SPIFFS.begin(true)){
@ -373,8 +376,8 @@ void setup() {
NVstore.init();
NVstore.load();
initMQTTJSONmoderator(); // prevent JSON for MQTT unless requested
initTimerJSONmoderator(); // prevent JSON for timers unless requested
initMQTTJSONmoderator(); // prevents JSON for MQTT unless requested
initTimerJSONmoderator(); // prevents JSON for timers unless requested
KeyPad.begin(keyLeft_pin, keyRight_pin, keyCentre_pin, keyUp_pin, keyDown_pin);
@ -437,7 +440,7 @@ void setup() {
#if USE_SW_WATCHDOG == 1
// create a watchdog timer
watchdogTimer = timerBegin(0, 80, true); //timer 0, divisor 80
timerAlarmWrite(watchdogTimer, 4000000, false); //set time in uS must be fed within this time or reboot
timerAlarmWrite(watchdogTimer, 15000000, false); //set time in uS must be fed within this time or reboot
timerAttachInterrupt(watchdogTimer, &interruptReboot, true);
timerAlarmEnable(watchdogTimer); //enable interrupt
#endif
@ -457,45 +460,7 @@ void loop()
float fTemperature;
unsigned long timenow = millis();
DebugPort.handle(); // keep telnet spy alive
#if USE_WIFI == 1
doWiFiManager();
#if USE_OTA == 1
DoOTA();
#endif // USE_OTA
#if USE_WEBSERVER == 1
bHaveWebClient = doWebServer();
#endif //USE_WEBSERVER
#endif // USE_WIFI
checkDebugCommands();
KeyPad.update(); // scan keypad - key presses handler via callback functions!
Bluetooth.check(); // check for Bluetooth activity
GPIOin.manage();
GPIOout.manage();
GPIOalg.manage();
// manage changes in Bluetooth connection status
if(Bluetooth.isConnected()) {
if(!bBTconnected) {
resetJSONmoderator(); // force full send upon BT client connect
}
bBTconnected = true;
}
else {
bBTconnected = false;
}
// manage changes in number of wifi clients
if(isWebServerClientChange()) {
resetJSONmoderator(); // force full send upon number of Wifi clients change
}
// DebugPort.handle(); // keep telnet spy alive
//////////////////////////////////////////////////////////////////////////////////////
// Blue wire data reception
@ -568,6 +533,9 @@ void loop()
feedWatchdog(); //reset timer (feed watchdog)
#endif
doStreaming(); // do wifi, BT tx etc when NOT in midst of handling blue wire
// this especially avoids E-07 faults due to larger data transfers
moderator = 50;
#if RX_LED == 1
@ -1344,5 +1312,53 @@ void ShowOTAScreen(int percent, bool webupdate)
void feedWatchdog()
{
uint64_t timeRem = timerRead(watchdogTimer);
if(timeRem > 100000) // 100ms
DebugPort.printf("WD time = %lld\r\n", timeRem); // print longer WD intervals
timerWrite(watchdogTimer, 0); //reset timer (feed watchdog)
}
void doStreaming()
{
#if USE_WIFI == 1
doWiFiManager();
#if USE_OTA == 1
DoOTA();
#endif // USE_OTA
#if USE_WEBSERVER == 1
bHaveWebClient = doWebServer();
#endif //USE_WEBSERVER
#endif // USE_WIFI
checkDebugCommands();
KeyPad.update(); // scan keypad - key presses handler via callback functions!
Bluetooth.check(); // check for Bluetooth activity
GPIOin.manage();
GPIOout.manage();
GPIOalg.manage();
// manage changes in Bluetooth connection status
if(Bluetooth.isConnected()) {
if(!bBTconnected) {
resetJSONmoderator(); // force full send upon BT client connect
}
bBTconnected = true;
}
else {
bBTconnected = false;
}
// manage changes in number of wifi clients
if(isWebServerClientChange()) {
resetJSONmoderator(); // force full send upon number of Wifi clients change
}
DebugPort.handle(); // keep telnet spy alive
}

View file

@ -152,9 +152,16 @@ CScreen::_reqOEMWarning()
}
void
CScreen::_drawBitmap(int x, int y, const BITMAP_INFO& info, uint16_t colour)
CScreen::_drawBitmap(int x, int y, const BITMAP_INFO& info, uint16_t colour, uint16_t bg)
{
_display.drawBitmap(x, y, info.pBitmap, info.width, info.height, colour);
if(bg == 0xffff) {
// normal mode - does not erase background
_display.drawBitmap(x, y, info.pBitmap, info.width, info.height, colour);
}
else {
// overwrite mode - erases background
_display.drawBitmap(x, y, info.pBitmap, info.width, info.height, colour, bg);
}
}

View file

@ -57,7 +57,7 @@ protected:
void _drawMenuSelection(CRect extents, const char* str, int border = 3, int radius = 4);
void _scrollMessage(int y, const char* str, int& charOffset);
void _reqOEMWarning();
void _drawBitmap(int x, int y, const BITMAP_INFO& info, uint16_t color = WHITE);
void _drawBitmap(int x, int y, const BITMAP_INFO& info, uint16_t color = WHITE, uint16_t bg = 0xffff);
public:
CScreen(C128x64_OLED& disp, CScreenManager& mgr);
virtual ~CScreen();

View file

@ -61,8 +61,6 @@
CScreenHeader::CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr) : CScreen(disp, mgr)
{
_clearUpAnimation = false;
_clearDnAnimation = false;
_colon = false;
}
@ -75,8 +73,7 @@ CScreenHeader::show()
// Bluetooth
showBTicon();
// WiFi
showWifiIcon();
// WiFi icon is updated in animate()
// battery
showBatteryIcon(getHeaterInfo().getBattVoltage());
@ -104,8 +101,8 @@ CScreenHeader::show()
bool
CScreenHeader::animate()
{
bool retval = true;
// animate timer icon,
// inserting an update icon if new firmware available from internet web server
_animateCount++;
ROLLUPPERLIMIT(_animateCount, 10, 0);
if(isUpdateAvailable(true)) {
@ -125,59 +122,9 @@ CScreenHeader::animate()
}
}
if((isWifiConnected() || isWifiAP()) && isWebClientConnected()) {
showWifiIcon();
int xPos = X_WIFI_ICON + WifiIconInfo.width;
// UP arrow animation
//
int yPos = 0;
bool uploadActive = hasWebServerSpoken(true);
if(_clearUpAnimation && !uploadActive) {
// arrow was drawn in the prior iteration, now erase it
if(NVstore.getOTAEnabled())
_display.fillRect(X_WIFI_ICON +12, Y_WIFI_ICON, 12, 5, BLACK);
else
_display.fillRect(xPos, yPos, WifiInIconInfo.width, WifiInIconInfo.height, BLACK);
_drawBitmap(X_WIFI_ICON, Y_WIFI_ICON, WifiIconInfo, WHITE);
retval = true;
_clearUpAnimation = false;
}
else if(uploadActive) {
// we have emitted data to the web client, show an UP arrow
if(NVstore.getOTAEnabled())
_display.fillRect(X_WIFI_ICON +12, Y_WIFI_ICON, 12, 5, BLACK);
else
_display.fillRect(xPos, yPos, WifiInIconInfo.width, WifiInIconInfo.height, BLACK);
_drawBitmap(X_WIFI_ICON, Y_WIFI_ICON, WifiIconInfo, WHITE);
_drawBitmap(xPos, yPos, WifiOutIconInfo);
_clearUpAnimation = true; // clear arrow upon next iteration
retval = true;
}
// DOWN arrow animation
//
yPos = WifiIconInfo.height - WifiInIconInfo.height + 1;
if(_clearDnAnimation) {
// arrow was drawn in the prior iteration, now erase it
_display.fillRect(X_WIFI_ICON + 12, Y_WIFI_ICON + 6, 12, 5, BLACK);
// _display.fillRect(xPos, yPos, W_WIFIOUT_ICON, H_WIFIOUT_ICON, BLACK);
_drawBitmap(X_WIFI_ICON, Y_WIFI_ICON, WifiIconInfo, WHITE);
retval = true;
_clearDnAnimation = false;
}
else if(hasWebClientSpoken(true)) {
// we have receievd data from the web client, show an DOWN arrow
_display.fillRect(X_WIFI_ICON + 12, Y_WIFI_ICON + 6, 12, 5, BLACK);
// _display.fillRect(xPos, yPos, W_WIFIOUT_ICON, H_WIFIOUT_ICON, BLACK);
_drawBitmap(X_WIFI_ICON, Y_WIFI_ICON, WifiIconInfo, WHITE);
_drawBitmap(xPos, yPos, WifiInIconInfo, WHITE);
_clearDnAnimation = true; // clear arrow upon next iteration
retval = true;
}
}
return retval; // true if we need to update the physical display
return true; // true if we need to update the physical display
}
void
@ -191,10 +138,41 @@ CScreenHeader::showBTicon()
void
CScreenHeader::showWifiIcon()
{
if(isWifiConnected() || isWifiAP()) {
_drawBitmap(X_WIFI_ICON, Y_WIFI_ICON, WifiIconInfo, WHITE);
if(isWifiConnected() || isWifiAP()) { // STA or AP mode active
_drawBitmap(X_WIFI_ICON, Y_WIFI_ICON, WifiWideIconInfo, WHITE, BLACK); // wide icon erases annotations!
int xPos = X_WIFI_ICON + WifiIconInfo.width + 1; // x loaction of upload/download arrows
// UP arrow animation
//
int yPos = 0;
if(hasWebServerSpoken(true)) {
// we have emitted data to the web client, show an UP arrow
_UpAnnotation.holdon = 2; // hold up arrow on for 2 cycles
_UpAnnotation.holdoff = 8; // hold blank for 8 cycles
};
if(_UpAnnotation.holdon) {
_UpAnnotation.holdon--;
_drawBitmap(xPos, yPos, WifiOutIconInfo); // add upload arrow
}
else if(_UpAnnotation.holdoff > 0) {
_UpAnnotation.holdoff--; // animation of arrow is now cleared
}
else {
if(NVstore.getOTAEnabled()) {
// OTA is enabled, show OTA
// erase top right portion of wifi icon
_display.fillRect(X_WIFI_ICON+11, Y_WIFI_ICON, 2, 6, BLACK);
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
_display.setCursor(X_WIFI_ICON+12, Y_WIFI_ICON);
_display.print("OTA");
}
}
// low side wifi icon annotation
if(isWifiButton()) {
_display.fillRect(X_WIFI_ICON + 11, Y_WIFI_ICON + 5, 15, 7, BLACK);
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
_display.setCursor(X_WIFI_ICON+12, Y_WIFI_ICON+6);
switch(isWifiButton()) {
@ -203,25 +181,40 @@ CScreenHeader::showWifiIcon()
case 3: _display.print("ERS"); break;
}
}
else if(isWifiConfigPortal()) {
_display.fillRect(X_WIFI_ICON + 11, Y_WIFI_ICON + 5, 15, 7, BLACK);
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
_display.setCursor(X_WIFI_ICON+12, Y_WIFI_ICON+6);
// _display.print("PTL");
_display.print("CFG");
}
else if(isWifiAP()) {
_display.fillRect(X_WIFI_ICON + 11, Y_WIFI_ICON + 5, 10, 7, BLACK);
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
_display.setCursor(X_WIFI_ICON+12, Y_WIFI_ICON+6);
_display.print("AP");
}
if(NVstore.getOTAEnabled()) {
_display.fillRect(X_WIFI_ICON +11, Y_WIFI_ICON, 14, 6, BLACK);
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
_display.setCursor(X_WIFI_ICON+12, Y_WIFI_ICON);
_display.print("OTA");
}
else {
// DOWN arrow animation
//
yPos = WifiIconInfo.height - WifiInIconInfo.height + 1;
if(hasWebClientSpoken(true)) {
// we have received data from the web client, show a DOWN arrow
_DnAnnotation.holdon = 2; // hold down arrow on for 2 cycles
_DnAnnotation.holdoff = 8; // hold blank for 8 cycles
}
if(_DnAnnotation.holdon) {
_DnAnnotation.holdon--;
_drawBitmap(xPos, yPos, WifiInIconInfo, WHITE); // add down arrow
}
else if(_DnAnnotation.holdoff > 0) {
_DnAnnotation.holdoff--; // nothing drawn after arrow, side annotation stays clear for a while
}
else {
// no activity for a while now
if(isWifiConfigPortal()) {
// if config portal, show CFG
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
_display.setCursor(X_WIFI_ICON+12, Y_WIFI_ICON+6);
_display.print("CFG");
}
else if(isWifiAP()) {
// if AP only, show AP
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
_display.setCursor(X_WIFI_ICON+12, Y_WIFI_ICON+6);
_display.print("AP");
}
}
}
}
}
@ -293,22 +286,3 @@ CScreenHeader::showTime()
}
}
void
CScreenHeader::showGPIO()
{
/* int xPos = X_GPIO_ICON; // both are enabled - draw icon 1 to the left, otherwise leave to the right
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
_display.setCursor(xPos, 0);
_display.print("1");
_display.drawBitmap(xPos + 4, 0, getGPIO(0) ? TickIcon : CrossIcon, TickIconWidth, TickIconHeight, WHITE);
_display.setCursor(xPos, 6);
_display.print("2");
_display.drawBitmap(xPos + 4, 6, getGPIO(1) ? TickIcon : CrossIcon, TickIconWidth, TickIconHeight, WHITE);*/
}
/*void
CScreenHeader::showGPIO()
{
int xPos = X_GPIO_ICON; // both are enabled - draw icon 1 to the left, otherwise leave to the right
_display.drawBitmap(xPos, 0, getGPIO(0) ? GPIO1ONIcon : GPIO1OFFIcon, GPIOIconWidthPixels, GPIOIconHeightPixels, WHITE);
_display.drawBitmap(xPos, 8, getGPIO(1) ? GPIO2ONIcon : GPIO2OFFIcon, GPIOIconWidthPixels, GPIOIconHeightPixels, WHITE);
}*/

View file

@ -27,10 +27,25 @@
#include "../Utility/UtilClasses.h"
#include "fonts/FontTypes.h"
struct sScreenholdoff {
int holdon;
int holdoff;
sScreenholdoff() {
reset();
}
void reset() {
holdon = 0;
holdoff = 0;
}
void set(int hldon = 2, int hldoff = 8) {
holdon = hldon;
holdoff = hldoff;
}
};
class CScreenHeader : public CScreen {
bool _clearUpAnimation;
bool _clearDnAnimation;
sScreenholdoff _UpAnnotation;
sScreenholdoff _DnAnnotation;
bool _colon;
int _animateCount;
protected:
@ -39,7 +54,6 @@ protected:
void showBatteryIcon(float voltage);
int showTimers();
virtual void showTime(); // x location depends upon how many timers are active
void showGPIO();
public:
CScreenHeader(C128x64_OLED& disp, CScreenManager& mgr);
bool show();

View file

@ -144,7 +144,7 @@ const BITMAP_INFO ThermoPtrIconInfo(3, 5, thermoPtr);
// 'Bluetooth icon', 6x11px
const unsigned char BTicon [] PROGMEM = {
0x20, // #
0x20, // #
0x30, // ##
0x28, // # #
0xa4, // # # #
@ -154,25 +154,41 @@ const unsigned char BTicon [] PROGMEM = {
0xa4, // # # #
0x28, // # #
0x30, // ##
0x20 // #
0x20 // #
};
const BITMAP_INFO BluetoothIconInfo(6, 11, BTicon);
// 'wifiIcon', 13x10px
const unsigned char wifiIcon [] PROGMEM = {
0x1f, 0xc0, // #######
0x1f, 0xc0, // #######
0x20, 0x20, // # #
0x40, 0x10, // # #
0x8f, 0x88, // # ##### #
0x10, 0x40, // # #
0x20, 0x20, // # #
0x07, 0x00, // ###
0x07, 0x00, // ###
0x08, 0x80, // # #
0x00, 0x00, //
0x02, 0x00 // #
};
const BITMAP_INFO WifiIconInfo(13, 10, wifiIcon);
// 'wifiIconWide', 13x10px
const unsigned char wifiwideIcon [] PROGMEM = {
0x1f, 0xc0, 0x00, 0x00, // #######
0x20, 0x20, 0x00, 0x00, // # #
0x40, 0x10, 0x00, 0x00, // # #
0x8f, 0x88, 0x00, 0x00, // # ##### #
0x10, 0x40, 0x00, 0x00, // # #
0x20, 0x20, 0x00, 0x00, // # #
0x07, 0x00, 0x00, 0x00, // ###
0x08, 0x80, 0x00, 0x00, // # #
0x00, 0x00, 0x00, 0x00, //
0x02, 0x00, 0x00, 0x00, // #
0x00, 0x00, 0x00, 0x00 //
};
const BITMAP_INFO WifiWideIconInfo(25, 11, wifiwideIcon);
// 'wifiInIcon, 5x5px
const unsigned char wifiInIcon [] PROGMEM = {
@ -214,7 +230,7 @@ const BITMAP_INFO BatteryIconInfo(15, 10, BatteryIcon);
// 'GlowPlugIcon', 16x9px
const unsigned char GlowPlugIcon [] PROGMEM = {
0x71, 0xc7, // ### ### ###
0x71, 0xc7, // ### ### ###
0x0e, 0x38, // ### ###
0x14, 0x14, // # # # #
0x12, 0x24, // # # # #
@ -222,21 +238,21 @@ const unsigned char GlowPlugIcon [] PROGMEM = {
0x11, 0x44, // # # # #
0x11, 0x44, // # # # #
0x0a, 0x28, // # # # #
0x0e, 0x38 // ### ###
0x0e, 0x38 // ### ###
};
const BITMAP_INFO GlowPlugIconInfo(16, 9, GlowPlugIcon);
// 'HeatRise', 17x2px
const unsigned char GlowHeatIcon [] PROGMEM = {
0x80, 0x00, 0x80, // # #
0x80, 0x00, 0x80, // # #
0x40, 0x01, 0x00 // # #
};
const BITMAP_INFO GlowHeatIconInfo(17, 2, GlowHeatIcon);
// 'Fan3_1a', 16x16px
const unsigned char FanIcon1 [] PROGMEM = {
0x03, 0xc0, // ####
0x03, 0xc0, // ####
0x04, 0x20, // # #
0x04, 0x20, // # #
0x04, 0x20, // # #
@ -244,7 +260,7 @@ const unsigned char FanIcon1 [] PROGMEM = {
0x03, 0xc0, // ####
0x07, 0xe0, // ######
0x06, 0x60, // ## ##
0x7e, 0x7e, // ###### ######
0x7e, 0x7e, // ###### ######
0x87, 0xe1, // # ### ### #
0x87, 0xe1, // # ### ### #
0x84, 0x21, // # # # #
@ -255,7 +271,7 @@ const unsigned char FanIcon1 [] PROGMEM = {
};
// 'Fan3_2a', 16x16px
const unsigned char FanIcon2 [] PROGMEM = {
0x00, 0x78, // ####
0x00, 0x78, // ####
0x00, 0x84, // # #
0x00, 0x84, // # #
0x00, 0x84, // # #
@ -270,21 +286,21 @@ const unsigned char FanIcon2 [] PROGMEM = {
0x00, 0x84, // # #
0x00, 0x84, // # #
0x00, 0x84, // # #
0x00, 0x78, // ####
0x00, 0x78, // ####
};
// 'Fan3_3a', 16x16px
const unsigned char FanIcon3 [] PROGMEM = {
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x78, 0x1e, // #### ####
0x84, 0x21, // # # # #
0x84, 0x21, // # # # #
0x87, 0xe1, // # ### ### #
0x87, 0xe1, // # #### ### #
0x7e, 0x7e, // ###### ######
0x7e, 0x7e, // ###### ######
0x06, 0x60, // ## ##
0x07, 0xe0, // ######
0x03, 0xc0, // ####
0x03, 0xc0, // ####
0x04, 0x20, // # #
0x04, 0x20, // # #
0x04, 0x20, // # #
@ -293,7 +309,7 @@ const unsigned char FanIcon3 [] PROGMEM = {
};
// 'Fan3_4a', 16x16px
const unsigned char FanIcon4 [] PROGMEM = {
0x1e, 0x00, // ####
0x1e, 0x00, // ####
0x21, 0x00, // # #
0x21, 0x00, // # #
0x21, 0x00, // # #
@ -308,7 +324,7 @@ const unsigned char FanIcon4 [] PROGMEM = {
0x21, 0x00, // # #
0x21, 0x00, // # #
0x21, 0x00, // # #
0x1e, 0x00 // ####
0x1e, 0x00 // ####
};
const BITMAP_INFO FanIcon1Info(16, 16, FanIcon1);
const BITMAP_INFO FanIcon2Info(16, 16, FanIcon2);
@ -318,7 +334,7 @@ const BITMAP_INFO FanIcon4Info(16, 16, FanIcon4);
// 'FuelIcon', 7x12px
const unsigned char FuelIcon [] PROGMEM = {
0x10, // #
0x10, // #
0x10, // #
0x38, // ###
0x38, // ###
@ -353,7 +369,6 @@ const BITMAP_INFO TargetIconInfo(13, 13, TargetIcon);
// 'repeat', 15x15px
const unsigned char repeatIcon [] PROGMEM = {
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
@ -361,7 +376,8 @@ const unsigned char repeatIcon [] PROGMEM = {
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x02, // #
0x00, 0x00,
0x00, 0x02, // #
0x00, 0x02, // #
0xf0, 0x04, // #### #
0xe0, 0x04, // ### #
@ -381,8 +397,8 @@ const unsigned char timerID1Icon [] PROGMEM = {
0x21, 0x08, // # # #
0x2d, 0x08, // # ## # #
0x25, 0xe8, // # # #### #
0x24, 0x08, // # # #
0x24, 0x08, // # # #
0x24, 0x08, // # # #
0x24, 0x08, // # # #
0x10, 0x10, // # #
0x08, 0x20, // # #
0x07, 0xc0, // #####
@ -401,7 +417,7 @@ const unsigned char timerID2Icon [] PROGMEM = {
0x21, 0x08, // # # #
0x2d, 0x08, // # ## # #
0x25, 0xe8, // # # #### #
0x28, 0x08, // # # #
0x28, 0x08, // # # #
0x2c, 0x08, // # ## #
0x10, 0x10, // # #
0x08, 0x20, // # #
@ -434,41 +450,41 @@ const BITMAP_INFO TimerIconInfo(15, 15, timerIcon);
// 'large timer', 15x15px
const unsigned char largeTimerIcon[] PROGMEM =
{
0x07, 0xC0, // #####
0x19, 0x30, // ## # ##
0x21, 0x08, // # # #
0x41, 0x04, // # # #
0x41, 0x04, // # # #
0x81, 0x02, // # # #
0x81, 0xF2, // # ##### #
0x80, 0x02, // # #
0x80, 0x02, // # #
0x80, 0x02, // # #
0x40, 0x04, // # #
0x40, 0x04, // # #
0x20, 0x08, // # #
0x18, 0x30, // ## ##
0x0F, 0xE0, // #######
0x07, 0xC0, // #####
0x19, 0x30, // ## # ##
0x21, 0x08, // # # #
0x41, 0x04, // # # #
0x41, 0x04, // # # #
0x81, 0x02, // # # #
0x81, 0xF2, // # ##### #
0x80, 0x02, // # #
0x80, 0x02, // # #
0x80, 0x02, // # #
0x40, 0x04, // # #
0x40, 0x04, // # #
0x20, 0x08, // # #
0x18, 0x30, // ## ##
0x0F, 0xE0, // #######
};
const BITMAP_INFO LargeTimerIconInfo(15, 15, largeTimerIcon);
const uint8_t PROGMEM verticalRepeatIcon [] =
{
0x78, // ####
0x38, // ###
0x38, // ###
0x48, // # #
0x80, // #
0x80, // #
0x80, // #
0x80, // #
0x80, // #
0x80, // #
0x80, // #
0x40, // #
0x40, // #
0x20, // #
0x20, // #
0x78, // ####
0x38, // ###
0x38, // ###
0x48, // # #
0x80, // #
0x80, // #
0x80, // #
0x80, // #
0x80, // #
0x80, // #
0x80, // #
0x40, // #
0x40, // #
0x20, // #
0x20, // #
};
const BITMAP_INFO VerticalRepeatIconInfo(15, 5, verticalRepeatIcon);

View file

@ -33,6 +33,7 @@ extern const BITMAP_INFO BluetoothIconInfo;
// 'wifiIcon', 13x10px
extern const BITMAP_INFO WifiIconInfo;
extern const BITMAP_INFO WifiWideIconInfo;
// 'wifiInIcon', 5x5px
extern const BITMAP_INFO WifiInIconInfo;

View file

@ -393,7 +393,11 @@ void updateJSONclients(bool report)
void resetJSONmoderator()
{
JSONmoderator.reset();
#ifdef SALWAYS_SEND_TIMERS
TimerModerator.reset();
#else
initTimerJSONmoderator();
#endif
initMQTTJSONmoderator();
}

View file

@ -132,6 +132,7 @@ void handleBTCNotFound() {
digitalWrite(led, 0);
}
// embedded HTML & Javascript to perform browser based updates of firmware or SPIFFS
const char* updateIndex = R"=====(
<!DOCTYPE html>
<html lang="en">
@ -233,22 +234,6 @@ const char* updateIndex = R"=====(
</html>
)=====";
const char* rootIndex = R"=====(
<!DOCTYPE html>
<script>
function init() {
window.location.assign("/");
}
</script
<html>
<head>
<title>HTML Meta Tag</title>
</head>
<body onload="javascript:init()">
<p>Root redirect</p>
</body>
</html>
)=====";
void rootRedirect()
{

View file

@ -263,18 +263,22 @@ void APstartedCallback(WiFiManager*)
const char* getWifiAPAddrStr()
{
noInterrupts();
static IPAddress IPaddr = WiFi.softAPIP(); // use stepping stone - function returns an automatic stack var - LAME!
interrupts();
return IPaddr.toString().c_str();
// noInterrupts();
IPAddress IPaddr = WiFi.softAPIP(); // use stepping stone - function returns an automatic stack var - LAME!
static char APIPaddr[16];
sprintf(APIPaddr, "%d.%d.%d.%d", IPaddr[0], IPaddr[1], IPaddr[2], IPaddr[3]);
// interrupts();
return APIPaddr;
}
const char* getWifiSTAAddrStr()
{
noInterrupts();
static IPAddress IPaddr = WiFi.localIP(); // use stepping stone - function returns an automatic stack var - LAME!
interrupts();
return IPaddr.toString().c_str();
// noInterrupts();
IPAddress IPaddr = WiFi.localIP(); // use stepping stone - function returns an automatic stack var - LAME!
static char STAIPaddr[16];
sprintf(STAIPaddr, "%d.%d.%d.%d", IPaddr[0], IPaddr[1], IPaddr[2], IPaddr[3]);
// interrupts();
return STAIPaddr;
}
const char* getWifiAPMACStr()