Help line code password on web server

I have an arduino esp32 web server program that simulates pressing buttons on the remote control.

Everything works correctly but I want to put the password on the server....I can't do it.

Can someone help me?

Thank you very much.

//#####################################
//##                                 ##
//## Diesel Heater Remote Controller ##
//## By Caschy 3/2023                ##
//## v4. portable-cel                ##
//#####################################
#include <Wire.h>
#include "Adafruit_HTU21DF.h" 
#include "RTClib.h"
#include <TFT_eSPI.h>
#include <SPI.h>
#include <EEPROM.h>
#include <WiFi.h>
#include <WebServer.h>
#include <WiFiManager.h>
#include <Preferences.h> 
#include <Update.h>
#include "My_Font.h"
#include "index.h"
#include "firm.h"

//Storage settings - preferences.h
Preferences preferences;

//HTU21D variables
Adafruit_HTU21DF myHTU = Adafruit_HTU21DF();
float tempf = 0.0;
float hum = 0.0;
 
//RTC variables
int myyear;
int mymonth;
int myday;
int myhour;
int myminute;
int mysecond;

//Button variables
#define BUTTON2PIN 35
#define BUTTON1PIN 0
long lastDebounceButton1 = 0;    // Holds Button1 last debounce
long lastDebounceButton2 = 0;    // Holds Button2 last debounce
long debounceDelay       = 250;  // 250ms between re-polling
int menuIndex = 0;
bool button2press = false;
bool button1press = false;
String screen = "main";
String button2sel[] = {"on","high","sub_menu","low","off","temp_menu","timer_menu","back","temp_down","ok","back","temp_up","five","twenty","forty","1hour","2hour","back"}; // index range = 0 to 17

//Power/Battery variables
#define POWEREN 14
#define ADC_PIN 34
float battery_voltage = 0.0;
int vref = 1100;

//Remote CTRL variables
int PowerOnPin=33;
int PowerOffPin=12;
int HzLowPin=13;
int HzHighPin=32;

//misc time variables
int period = 10000;
int preiodt = 120000;
long previousMillis = 0;
int targTemp = 0;
bool targTempSet = false;
String tempSetMode = "none";
String tempSetModePrev = "none";
bool timerSet = false;
int targYear = 0;
int targMonth = 0;
int targDay = 0;
int targHour = 0;
int targMinute = 0;
long targUnix = 0;

//wifi variables
String ssid="";
String pass="";

// Set heater ctrl web server port number to 80
WebServer server(9636);



//Graphics variables
static const uint8_t  PROGMEM cbclogo[] = {
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x80,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x80,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x80,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x80,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x80,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x80,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xfb,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0x1,0xf8,0x0,0x0,0x1,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0x1,0xf8,0x0,0x0,0x1,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0x1,0xf8,0x0,0x0,0x1,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0x1,0xf8,0x0,0x0,0x1,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0x1,0xf8,0x0,0x0,0x3,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfc,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfc,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0x7,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0xf,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0x7,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x0,0x0,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xff,0xc7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xff,0x87,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xfe,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf0,0xf,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf0,0x3f,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf0,0x87,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xfe,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf0,0xf,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf0,0x1f,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf0,0xc7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xfb,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xfc,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0xf,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x1f,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x67,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf9,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xfc,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x1f,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x6f,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf9,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xfe,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x1f,0xff,0xff,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x0,0x0,0x0,0xf8,0x7,0xfe,0x1,0xf8,0x7,0xff,0xff,
0x80,0x0,0x0,0x0,0x70,0x8,0x0,0x1,0xf8,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x70,0x30,0x0,0x1,0xf8,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x78,0x80,0x0,0x1,0xf8,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x7a,0x0,0x0,0x1,0xf8,0x0,0x0,0x1,
0xdf,0xff,0xff,0xfe,0xfc,0x0,0x0,0x1,0xf8,0x0,0x0,0x1,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};

static const uint8_t  PROGMEM checkm[] = {
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x40,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x0,0x40,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x0,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x1,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x3,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x3,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x7,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0xf,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x0,0x1f,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x0,0x3f,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x0,0x7f,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x0,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x0,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x1,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x3,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x0,0x7,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0,0xf,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x0,0x1f,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x0,0x1f,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x0,0x3f,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x0,0x7f,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x0,0x1,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x0,0x3,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0,0x3,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x0,0x7,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x0,0xf,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x0,0x1f,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x3f,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x0,0x0,0x3f,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x0,0x0,0x7f,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x0,0x1,0xff,0xff,0xff,0xc0,
0xff,0xbf,0xff,0xff,0xff,0xff,0xe0,0x0,0x1,0xff,0xff,0xff,0xc0,
0xff,0x1f,0xff,0xff,0xff,0xff,0xc0,0x0,0x3,0xff,0xff,0xff,0xc0,
0xfe,0xf,0xff,0xff,0xff,0xff,0x80,0x0,0x7,0xff,0xff,0xff,0xc0,
0xfc,0x7,0xff,0xff,0xff,0xff,0x0,0x0,0xf,0xff,0xff,0xff,0xc0,
0xf8,0x3,0xff,0xff,0xff,0xfe,0x0,0x0,0x1f,0xff,0xff,0xff,0xc0,
0xf0,0x1,0xff,0xff,0xff,0xfc,0x0,0x0,0x1f,0xff,0xff,0xff,0xc0,
0xe0,0x0,0xff,0xff,0xff,0xf8,0x0,0x0,0x3f,0xff,0xff,0xff,0xc0,
0xc0,0x0,0x3f,0xff,0xff,0xf0,0x0,0x0,0x7f,0xff,0xff,0xff,0xc0,
0x80,0x0,0x1f,0xff,0xff,0xe0,0x0,0x0,0xff,0xff,0xff,0xff,0xc0,
0x0,0x0,0xf,0xff,0xff,0xc0,0x0,0x0,0xff,0xff,0xff,0xff,0xc0,
0x80,0x0,0x7,0xff,0xff,0x80,0x0,0x1,0xff,0xff,0xff,0xff,0xc0,
0xc0,0x0,0x3,0xff,0xff,0x0,0x0,0x3,0xff,0xff,0xff,0xff,0xc0,
0xe0,0x0,0x1,0xff,0xfe,0x0,0x0,0x7,0xff,0xff,0xff,0xff,0xc0,
0xf0,0x0,0x0,0xff,0xfc,0x0,0x0,0x7,0xff,0xff,0xff,0xff,0xc0,
0xf8,0x0,0x0,0x7f,0xf8,0x0,0x0,0xf,0xff,0xff,0xff,0xff,0xc0,
0xfc,0x0,0x0,0x3f,0xf0,0x0,0x0,0x1f,0xff,0xff,0xff,0xff,0xc0,
0xfe,0x0,0x0,0xf,0xe0,0x0,0x0,0x1f,0xff,0xff,0xff,0xff,0xc0,
0xff,0x0,0x0,0x7,0xc0,0x0,0x0,0x3f,0xff,0xff,0xff,0xff,0xc0,
0xff,0x80,0x0,0x3,0x80,0x0,0x0,0x7f,0xff,0xff,0xff,0xff,0xc0,
0xff,0xc0,0x0,0x1,0x0,0x0,0x0,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xe0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xf0,0x0,0x0,0x0,0x0,0x1,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xf8,0x0,0x0,0x0,0x0,0x3,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xfc,0x0,0x0,0x0,0x0,0x3,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xfe,0x0,0x0,0x0,0x0,0x7,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0x0,0x0,0x0,0x0,0xf,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0x80,0x0,0x0,0x0,0xf,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xc0,0x0,0x0,0x0,0x1f,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xe0,0x0,0x0,0x0,0x3f,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xf0,0x0,0x0,0x0,0x3f,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xf8,0x0,0x0,0x0,0x7f,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xfc,0x0,0x0,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xfe,0x0,0x0,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0x0,0x0,0x1,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0x0,0x0,0x3,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0x80,0x0,0x3,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xc0,0x0,0x7,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xe0,0x0,0xf,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xf0,0x0,0xf,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xf8,0x0,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xfc,0x0,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xfe,0x0,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0x0,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0x80,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xc1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xe1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xf3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0
};

static const uint8_t  PROGMEM engine[] = {
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x0,0x0,0x0,0x0,0x0,
0x0,0x7f,0xff,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xff,0x0,0x0,0x0,0x0,
0x0,0x80,0x7,0xff,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xff,0xff,0x0,0x0,0x0,
0x1,0x80,0x0,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,
0x1,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x3,0x8,0x0,0x0,0x0,0x0,0x60,0x0,0x0,
0x2,0x0,0x0,0x0,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x70,0x0,0x0,
0x2,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x0,0x0,
0x2,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38,0x0,0x0,
0x6,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x3c,0x0,0x0,
0x4,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x1c,0x0,0x0,
0x4,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x1e,0x0,0x0,
0xc,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x1e,0x0,0x0,
0x8,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0xb,0x0,0x0,
0x8,0x7f,0xfc,0x0,0x80,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x9,0xfc,0x0,
0x9,0x80,0x3e,0x1,0x80,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0xc,0x7e,0x0,
0xe,0x0,0xf,0x81,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0xc,0x3,0x0,
0xc,0x3e,0x7,0xc1,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x4,0x3,0x0,
0x18,0x3c,0x3,0xc1,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x4,0x3,0x0,
0x10,0x18,0x11,0xe2,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x4,0x1,0x0,
0x22,0x10,0x79,0xb2,0x0,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x66,0x0,0x7c,0x92,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x46,0x0,0x1c,0x92,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x4f,0x0,0x0,0x5a,0x0,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x4f,0x4,0x0,0x4e,0x0,0x0,0x3,0xe0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x3,0xe,0x0,0x4e,0x0,0x3,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x40,0xe,0x0,0x4f,0xff,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x40,0xe,0x1c,0x4f,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x40,0x0,0x1e,0x4e,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x44,0x0,0xc,0xd2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x67,0xc0,0xc,0x92,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1,0x80,
0x23,0xc0,0x8,0x92,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x1,0x80,
0x33,0x83,0x9,0x22,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x1,0x0,
0x18,0x7,0x3,0x62,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x3,0x0,
0x1c,0xf,0x3,0xc2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc,0x3,0x0,
0xe,0xe,0xf,0x83,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc,0x3,0x0,
0x3,0x0,0x1f,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc,0x2,0x0,
0x1,0xf0,0xfc,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0xfe,0x0,
0x0,0xff,0xe0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x19,0xfe,0x0,
0x0,0xc0,0x0,0x1,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x19,0x80,0x0,
0x0,0x60,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x13,0x0,0x0,
0x0,0x30,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x33,0x0,0x0,
0x0,0x30,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x36,0x0,0x0,
0x0,0x18,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,0x0,0x0,
0x0,0xc,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,0x0,0x0,
0x0,0xe,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,
0x0,0x6,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,
0x0,0x3,0x0,0x0,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xe0,0x0,0x0,
0x0,0x1,0xff,0x80,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xe0,0x0,0x0,
0x0,0x0,0xf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xc0,0x0,0x0,
0x0,0x0,0x0,0x0,0x67,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x21,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x21,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x21,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x21,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x21,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x21,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
};

static const uint8_t  PROGMEM flame[] = {
0x0,0x0,0x0,
0x0,0x0,0x0,
0x0,0x0,0x0,
0x0,0x0,0x0,
0x0,0xc0,0x0,
0x0,0xc0,0x0,
0x0,0xc0,0x0,
0x1,0xc0,0x0,
0x1,0xc0,0x0,
0x1,0xc0,0x0,
0x1,0xc0,0x0,
0x1,0xe0,0x0,
0x1,0xe0,0x0,
0x0,0xf0,0x0,
0x0,0x78,0x0,
0x0,0x70,0x60,
0x0,0x7c,0x60,
0x8,0x7f,0xe0,
0x8,0x7f,0xf0,
0x8,0x7f,0xf0,
0x8,0x61,0xf0,
0x1f,0xe1,0xf8,
0x3f,0xe1,0xf8,
0x3f,0xe1,0xf8,
0x7c,0x1,0xf8,
0x7c,0x1,0xfc,
0x7c,0x0,0x7c,
0x78,0x0,0x7c,
0x78,0x0,0x7c,
0x78,0x0,0x38,
0x78,0x0,0x18,
0x38,0x0,0x30,
0x18,0x0,0x0,
0x8,0x0,0x0,
0x0,0x0,0x0,
0x0,0x0,0x0
};

RTC_DS3231 rtc;
TFT_eSPI tft = TFT_eSPI();

// Interrupt Function to execute when Button 1 is Pushed
void IRAM_ATTR toggleButton1() {
  if ((millis() - lastDebounceButton1) > debounceDelay) { 
    button1press= true;
    lastDebounceButton1 = millis();
  }
}

// Interrupt Function to execute when Button 2 is Pushed
void IRAM_ATTR toggleButton2() {
  if ((millis() - lastDebounceButton2) > debounceDelay) { 
    button2press = true;
    lastDebounceButton2 = millis();
  }
}

void writeLongIntoEEPROM(int address, long number)
{ 
  EEPROM.write(address, (number >> 24) & 0xFF);
  EEPROM.write(address + 1, (number >> 16) & 0xFF);
  EEPROM.write(address + 2, (number >> 8) & 0xFF);
  EEPROM.write(address + 3, number & 0xFF);
}

long readLongFromEEPROM(int address)
{
  return ((long)EEPROM.read(address) << 24) +
         ((long)EEPROM.read(address + 1) << 16) +
         ((long)EEPROM.read(address + 2) << 8) +
         (long)EEPROM.read(address + 3);
}

void RTCSetup() {
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    tft.println("Couldn't find RTC");
	Serial.flush();
    abort();
  }
}

void RTCSetupTime() {
  String hrr, mn, monthy, dayy, yeary;
  
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  //rtc.adjust(DateTime(2022, 12, 27, 15, 32, 0));
  if (server.arg("hr") == ""){     //Parameter not found
     Serial.print("hr/Argument not found");
  }else{     //Parameter found
    hrr = server.arg("hr");
    Serial.print("Hour = " + hrr);
  }
  if (server.arg("min") == ""){     //Parameter not found
     Serial.print("minute/Argument not found");
  }else{     //Parameter found
    mn = server.arg("min");
    Serial.print("Minute = " + mn);
  }
  if (server.arg("yr") == ""){     //Parameter not found
     Serial.print("year/Argument not found");
  }else{     //Parameter found
    yeary = server.arg("yr");
    Serial.print("Year = " + yeary);
  }
  if (server.arg("mon") == ""){     //Parameter not found
     Serial.print("month/Argument not found");
  }else{     //Parameter found
    monthy = server.arg("mon");
    Serial.print("Month = " + monthy);
  }
  if (server.arg("day") == ""){     //Parameter not found
     Serial.print("day/Argument not found");
  }else{     //Parameter found
    dayy = server.arg("day");
    Serial.print("Day = " + dayy);
  }
  Serial.println("");
  //template rtc.adjust(DateTime(2022, 12, 27, 15, 32, 0));
 if ((server.arg("hr") != "") && (server.arg("min") != "") && (server.arg("yr") != "") && (server.arg("mon") != "") && (server.arg("day") != "")){ 
    rtc.adjust(DateTime(yeary.toInt(), monthy.toInt(), dayy.toInt(), hrr.toInt(), mn.toInt(), 0));
    Serial.print("Time set");
    server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"30 ; url='/'\" /></head>Time set successfully, rebooting ctrlr. This page will refresh in 30 seconds.</html>");
 }
 else{
  Serial.print("Error, time not set!");
  server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"30 ; url='/'\" /></head>ERROR: Time NOT set, rebooting ctrlr. This page will refresh in 30 seconds.</html>");
 }
}

void readRTCTime() {
  DateTime now = rtc.now();
  mymonth = now.month();
  myday = now.day();
  myyear = now.year();
  
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_22);
  int tot = 0;
  if (mymonth >= 10) {
    tot = tot + 2;
  }
  else {
    tot = tot + 1;
  }
  if (myday >= 10) {
    tot = tot + 2;
  }
  else {
    tot = tot + 1;
  }
  tot = tot + 6;
  if (tot > 8) {
    tft.setCursor(1, 95);
  }
  else {
    tft.setCursor(14, 95);
  }
  tft.print(mymonth);
  tft.print('/');
  tft.print(myday);
  tft.print('/');
  tft.println(myyear);

  myhour = now.hour();
// DST ?
//  if ((mymonth >=3) && (mymonth <= 10)) {
//   myhour = myhour + 1;
//  }
  myminute = now.minute();
  
  tft.setFreeFont(&Lato_Heavy_42);
  tft.setCursor(8, 145);
  if (myhour < 10) {
    tft.print(' ');
    tft.print(myhour);
  }
  else {
    tft.print(myhour);  
  }
  
  tft.print(':');
  
  if (myminute < 10) {
   tft.print('0');
   tft.print(myminute);
  }
  else {
   tft.print(myminute);
  }
}

void readTempHum()
{
   hum = 0;
   hum = myHTU.readHumidity();
   
   tempf = 0;
   tempf = myHTU.readTemperature(); 
   //tempf = (tempf * 1.8) + 32;

   // Check if any reads failed and exit early (to try again).
   if (isnan(hum) || isnan(tempf)) {
    Serial.println("Failed to read from sensor!");
    hum = 0;
    tempf = 0.0;
    return;
   }
}

void readBattery() {
  uint16_t v = analogRead(ADC_PIN);
  battery_voltage = ((float)v / 4095.0) * 2.0 * 3.3 * (vref / 1000.0);
}

void showTempHum() {
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_18);
  tft.setCursor(0, 22);
  tft.print(hum,0);
  tft.println("%");

  if (tempf < 15.5) {
    tft.setTextColor(TFT_BLUE, TFT_BLACK);
  }
  else if ((tempf >= 15.5) && (tempf < 22.2)) {
    tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  }
  else {
    tft.setTextColor(TFT_RED, TFT_BLACK);
  }
  tft.setFreeFont(&Lato_Heavy_22);
  tft.setCursor(39, 50);
  tft.print(tempf,1);
  tft.print(" C");
  tft.drawCircle(89,39,2,TFT_WHITE);
}

void showBattery() {
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_18);
  tft.setCursor(94, 22);
  tft.print(battery_voltage,1);
  tft.print('V');
}

void showMain() {
  screen = "main";
  
     //clear temp/hum/battery section of screen
     //tft.fillRect(0,0,40,25,TFT_BLACK);
     //tft.fillRect(90,0,130,25,TFT_BLACK);
     //tft.fillRect(30,30,80,32,TFT_BLACK);
     tft.setTextColor(TFT_BLACK, TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_18);
     tft.setCursor(0, 22);
     tft.print(hum,0);
     tft.println("%");

     tft.setFreeFont(&Lato_Heavy_22);
     tft.setCursor(39, 50);
     tft.print(tempf,1);
     tft.print(" C");
     
     //clear date/time section of screen
     tft.fillRect(0,85,130,70,TFT_BLACK);
  
     //Get RTC Time and show it
     readRTCTime();
     //Read temperature and humidity
     readTempHum();
     //Read Battery
     //readBattery();
  
     //Display Temp Hum
     showTempHum();
     //Display Battery
     //showBattery();
}

void showAndMonitorTemperature() {
  int hyst = 5;
  unsigned long time_now = millis();
  screen = "main";
     //clear temp/hum/battery section of screen
     tft.fillRect(0,0,40,25,TFT_BLACK);
     tft.fillRect(90,0,130,25,TFT_BLACK);
     tft.fillRect(30,30,80,32,TFT_BLACK);
     //clear date/time section of screen
     tft.fillRect(0,85,130,70,TFT_BLACK);
  
     //Get RTC Time and show it
     readRTCTime();
     //Read temperature and humidity
     readTempHum();
     //Read Batrery
     //readBattery();
  
     //Display Temp Hum
     showTempHum();
     //Display Battery
     //showBattery();
  
     //Display targ temperature set
     tft.setTextColor(TFT_YELLOW, TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_18);
     tft.setCursor(0, 50);
     tft.print(targTemp);
     tft.print("C");

   time_now = millis();
   if ((time_now - previousMillis) >= period){
     previousMillis = time_now;
   
     //monitor and execute appropriate remote control transmissions
     Serial.print("Targ = ");
     Serial.print(targTemp);
     Serial.print(", Cur = ");
     Serial.print(int(tempf));
     Serial.print(", Diff = ");
     Serial.print(int(tempf)-targTemp);
     Serial.print(", Mode = ");
     Serial.print(tempSetMode);
     Serial.print(", Prev Mode = ");
     Serial.println(tempSetModePrev);

    if (((int(tempf)-targTemp) < hyst) && ((int(tempf)-targTemp) <= 0)) {
        //Cold temp threshold reached....send HEATER HIGH
        // if first time through loop/check
        if (tempSetMode == "none") {   
         Serial.println("Target Temperature set....sending heater high mode");
         Serial.println("1st heat");
         //send high, step .5 hz
         //execute
         tft.fillTriangle(90,180,80,200,100,200,TFT_GREEN);
         //for (int c=1;c<=5;c++){
          digitalWrite(HzHighPin, HIGH);
          delay(800);
          digitalWrite(HzHighPin, LOW);
          delay(800);
         //}
         tft.fillTriangle(90,180,80,200,100,200,TFT_BLACK);
         tempSetMode = "heat";
         tempSetModePrev = "none";
        }
    else if (tempSetMode == "cool") {
     if (abs(int(tempf)-targTemp) >= hyst) {
           //now make sure we check to see if/when temp gets too high, we need to turn heater on low to lower temperature
           Serial.println("Temp too low...turning heater high");
           Serial.println("low diff, sent high");
           //send high, step .5 hz
           //execute
           tft.fillTriangle(90,180,80,200,100,200,TFT_GREEN);
           //for (int c=1;c<=5;c++){
            digitalWrite(HzHighPin, HIGH);
            delay(800);
            digitalWrite(HzHighPin, LOW);
            delay(800);
           //}
           tft.fillTriangle(90,180,80,200,100,200,TFT_BLACK);
           tempSetModePrev = "cool";
           tempSetMode = "heat";
         }
    }
    }
     else if (((int(tempf)-targTemp) >= hyst) && ((int(tempf)-targTemp) >= 0)) {
        //Hot temp threshold reached...send HEATER LOW
        // if first time through loop/check
        if (tempSetMode == "none") {   
         Serial.println("Target Hot Temperature reached....sending heater low mode");
         Serial.println("1st cool");
         //send low, step .5 hz
         //execute
         tft.fillTriangle(90,200,80,180,100,180,TFT_RED);
         //for (int c=1;c<=5;c++){
          digitalWrite(HzLowPin, HIGH);
          delay(800);
          digitalWrite(HzLowPin, LOW);
          delay(800);
         //}
         tft.fillTriangle(90,200,80,180,100,180,TFT_BLACK);
         tempSetMode = "cool";
         tempSetModePrev = "none";
        }
    else if (tempSetMode == "heat") {
      if (abs(int(tempf)-targTemp) >= hyst) {
           //now make sure we check to see if/when temp gets too high, we need to turn heater on low to lower temperature
           Serial.println("Temp too high...turning heater low");
           Serial.println("Heat diff, sent low");
           //send low, step .5 hz
           //execute
           tft.fillTriangle(90,200,80,180,100,180,TFT_RED);
           //for (int c=1;c<=5;c++){
            digitalWrite(HzLowPin, HIGH);
            delay(800);
            digitalWrite(HzLowPin, LOW);
            delay(800);
           //}       
           tft.fillTriangle(90,200,80,180,100,180,TFT_BLACK);
           tempSetModePrev = "heat";
           tempSetMode = "cool";
          }
    }
    }  
   }
}

void showAndMonitorTime() {
  unsigned long time_now = millis();
  screen = "main";
     //clear temp/hum/battery section of screen
     tft.fillRect(0,0,40,25,TFT_BLACK);
     //tft.fillRect(90,0,130,25,TFT_BLACK);
     tft.fillRect(30,30,80,31,TFT_BLACK);
     //clear date/time section of screen
     tft.fillRect(0,85,130,70,TFT_BLACK);
  
     //Get RTC Time and show it
     readRTCTime();
     //Read temperature and humidity
     readTempHum();
     //Read Batrery
     //readBattery();
  
     //Display Temp Hum
     showTempHum();
     //Display Battery
     //showBattery();
  
     //Display targ temperature set
     tft.setTextColor(TFT_YELLOW, TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_14);
     tft.setCursor(2, 70);
     tft.print(targMonth);
     tft.print("/");
     tft.print(targDay);
     tft.print("/");
     tft.print(targYear);
     tft.print(" ");
     if (targHour < 10) {
      tft.print(" ");
      tft.print(targHour);
     }
     else {
      tft.print(targHour);
     }
     tft.print(":");
     if (targMinute < 10) {
      tft.print("0");
      tft.print(targMinute);
     }
     else {
      tft.print(targMinute);
     }

   time_now = millis();
   if ((time_now - previousMillis) >= period){
     previousMillis = time_now;
     //monitor and execute appropriate remote control transmissions
     if (rtc.now().unixtime() >= targUnix) {
      //timer done/reached - send HEATER OFF
      Serial.println("TIMER DONE!!!");
      Serial.println(targUnix);
      tft.fillScreen(TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_24);
      tft.setTextColor(TFT_RED, TFT_BLACK);
      tft.setCursor(30, 120);
      //execute
      digitalWrite(PowerOffPin, HIGH);
      delay(800);
      digitalWrite(PowerOffPin, LOW);
      delay(1000);
      tft.println("TIMER");
      tft.setCursor(0, 160);
      tft.println("HEAT OFF");
      delay(10000);
      screen = "main";
      timerSet = false;
      menuIndex=0;

     //clear screen
     tft.fillScreen(TFT_BLACK);
     //draw background engine
     tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
     
     //show Main GUI menu
     tft.drawRect(0, 215, 40, 28, TFT_WHITE);
     tft.fillRect(2, 217, 37, 26, TFT_GREEN);
     tft.drawRect(45, 215, 40, 28, TFT_WHITE);
     tft.drawRect(90, 215, 40, 28, TFT_WHITE);
     tft.fillRect(92, 217, 37, 26, TFT_RED);

     tft.drawLine(58, 226, 72, 226, TFT_WHITE);
     tft.drawLine(58, 231, 72, 231, TFT_WHITE);
     tft.drawLine(58, 236, 72, 236, TFT_WHITE);
  
     tft.setTextColor(TFT_BLACK, TFT_GREEN);
     tft.setFreeFont(&Lato_Heavy_14);
     tft.setCursor(9, 235);
     tft.print("ON");

     tft.setTextColor(TFT_GREEN, TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_14);
     tft.setCursor(48, 235);
     tft.print("+");

     tft.setTextColor(TFT_BLACK, TFT_RED);
     tft.setFreeFont(&Lato_Heavy_14);
     tft.setCursor(97, 235);
     tft.print("OFF");

     tft.setTextColor(TFT_RED, TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_14);
     tft.setCursor(75, 235);
     tft.print("-");

     //draw flame cursor
     tft.drawBitmap(8, 215, flame, 24, 28, TFT_ORANGE);  

     }
   }
}

void showMainMenu() {

  //show Main GUI menu
  tft.drawRect(0, 215, 40, 28, TFT_WHITE);
  tft.fillRect(2, 217, 37, 26, TFT_GREEN);
  tft.drawRect(45, 215, 40, 28, TFT_WHITE);
  tft.drawRect(90, 215, 40, 28, TFT_WHITE);
  tft.fillRect(92, 217, 37, 26, TFT_RED);

  tft.drawLine(58, 226, 72, 226, TFT_WHITE);
  tft.drawLine(58, 231, 72, 231, TFT_WHITE);
  tft.drawLine(58, 236, 72, 236, TFT_WHITE);
  
  tft.setTextColor(TFT_BLACK, TFT_GREEN);
  tft.setFreeFont(&Lato_Heavy_14);
  tft.setCursor(9, 235);
  tft.print("ON");

  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_14);
  tft.setCursor(48, 235);
  tft.print("+");

  tft.setTextColor(TFT_BLACK, TFT_RED);
  tft.setFreeFont(&Lato_Heavy_14);
  tft.setCursor(97, 235);
  tft.print("OFF");

  tft.setTextColor(TFT_RED, TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_14);
  tft.setCursor(75, 235);
  tft.print("-");
  
  //draw flame cursor
  tft.drawBitmap(8, 215, flame, 24, 28, TFT_ORANGE);  

}

void setLow() {
  //send low, step .1 hz per loop for total of .5 hz
  //execute
  tft.fillTriangle(90,200,80,180,100,180,TFT_RED);
  //for (int c=1;c<=5;c++){
   digitalWrite(HzLowPin, HIGH);
   delay(800);
   digitalWrite(HzLowPin, LOW);
   delay(800);
  //}
  tft.fillTriangle(90,200,80,180,100,180,TFT_BLACK);  
}

void setHigh() {
  //send high, step .1 hz per loop for total of .5 hz
  //execute
  tft.fillTriangle(90,180,80,200,100,200,TFT_GREEN);
  //for (int c=1;c<=5;c++){
   digitalWrite(HzHighPin, HIGH);
   delay(800);
   digitalWrite(HzHighPin, LOW);
   delay(800);
  //}
  tft.fillTriangle(90,180,80,200,100,200,TFT_BLACK);
}

void setLowGUI() {
  //send low
  //execute
  tft.fillTriangle(90,200,80,180,100,180,TFT_RED);
  digitalWrite(HzLowPin, HIGH);
  delay(800);
  digitalWrite(HzLowPin, LOW);
  screen = "main";
  targTempSet = false;
  delay(1000);
  tft.fillTriangle(90,200,80,180,100,180,TFT_BLACK);  
  showMainMenu();
}

void setHighGUI() {
  //send high
  //execute
  tft.fillTriangle(90,180,80,200,100,200,TFT_GREEN);
  digitalWrite(HzHighPin, HIGH);
  delay(800);
  digitalWrite(HzHighPin, LOW);
  screen = "main";
  targTempSet = false;
  delay(1000);
  tft.fillTriangle(90,180,80,200,100,200,TFT_BLACK);
  showMainMenu();
}

void powerOn() {
 //GUI stuff
 //draw engine on
 tft.fillTriangle(100,190,80,180,80,200,TFT_GREEN);

  //execute
 digitalWrite(PowerOnPin, HIGH);
 delay(800);
 digitalWrite(PowerOnPin, LOW);
 screen = "main";
 targTempSet = false;
 delay(2000);
 tft.fillTriangle(100,190,80,180,80,200,TFT_BLACK);
 showMainMenu();
}

void powerOff() {
 //GUI stuff
 //draw engine off
 tft.fillRect(80,180,20,20,TFT_RED);
 
 //execute
 digitalWrite(PowerOffPin, HIGH);
 delay(800);
 digitalWrite(PowerOffPin, LOW);
 screen = "main";
 targTempSet = false;
 delay(2000);
 tft.fillRect(80,180,20,20,TFT_BLACK);
 showMainMenu();
}

void sub_main() {
  //GUI stuff
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_28);
  tft.setCursor(0, 90);
  tft.println("[-]TEMP");
  tft.setTextColor(0x8410, TFT_BLACK);  //set inactive items gray
  tft.println("[ ]TIMER");
  tft.println("[ ]BACK");
  menuIndex = 5;
}

void temperatureSet() {
  //GUI stuff
  tft.fillScreen(TFT_BLACK);
  //Read temperature and humidity
  readTempHum();
  //Display Temp Hum
  showTempHum();
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_46);
  tft.setCursor(41, 150);
  targTemp = int(tempf)+2;
  tft.println(targTemp);
  tft.fillTriangle(20,240,0,200,40,200,TFT_BLUE);
  tft.fillTriangle(110,200,90,240,130,240,0x8410);
  tft.fillRect(54,200,30,18,0x8410);
  tft.fillRect(54,221,30,18,0x8410);
  tft.setTextColor(TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_12);
  tft.setCursor(58,215);
  tft.println("OK"); 
  tft.setCursor(57,235);
  tft.println("Bck"); 
  
}

void timerSetGUI() {
  //GUI stuff
  tft.fillScreen(TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_28);
  tft.setCursor(0, 40);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  tft.println("[-]5 Min");
  tft.setTextColor(0x8410, TFT_BLACK);
  tft.println("[ ]20 Min");
  tft.setTextColor(0x8410, TFT_BLACK);
  tft.println("[ ]40 Min");
  tft.setTextColor(0x8410, TFT_BLACK);
  tft.println("[ ]60 Min");
  tft.setTextColor(0x8410, TFT_BLACK);
  tft.println("[ ]120 Mn");
  tft.setTextColor(0x8410, TFT_BLACK);
  tft.println("[ ]BACK");
  
}

//------------WEB SERVER------------------------------------------------------------------------------------------------------------------
void handle_OnConnect() {
  String s = MAIN_page; //Read HTML contents
  server.send(200, "text/html", s); //Send web page
}

void handle_readDATA() {  
  DateTime htmlnow = rtc.now(); 
  String htmlminute,tm;

  if (htmlnow.minute() < 10) {
   htmlminute="0"+String(htmlnow.minute());
  }
  else {
   htmlminute=String(htmlnow.minute());
  }
  tm = String(htmlnow.hour())+":"+htmlminute;
  
  //get battery voltage
  readBattery();
  
  if (targTempSet) {
    server.send(200, "text/plane", String(tempf,1)+"|"+tm+"|"+String(battery_voltage,1)+"|"+String(hum)+"|"+String(targTemp)); 
  } else if (timerSet) {
    server.send(200, "text/plane", String(tempf,1)+"|"+tm+"|"+String(battery_voltage,1)+"|"+String(hum)+"|"+String(targMonth)+"/"+String(targDay)+"/"+String(targYear)+" "+String(targHour)+":"+String(targMinute)); 
  } else {
   server.send(200, "text/plane", String(tempf,1)+"|"+tm+"|"+String(battery_voltage,1)+"|"+String(hum)+"| "); 
  }
}

void handle_readPins() {
  Serial.println("Query for Remote GPIO pins requested and sent");
  server.send(200, "text/plane", String(PowerOnPin)+"|"+String(PowerOffPin)+"|"+String(HzLowPin)+"|"+String(HzHighPin)); 
}

void handle_configWifi() {
  WiFiManager wm;
  wm.resetSettings();
  delay(2000);
  ESP.restart();
}
void handle_reboot() { 
 tft.fillScreen(TFT_BLACK);
 tft.setFreeFont(&Lato_Heavy_14); 
 tft.setCursor(0, 40);
 tft.setTextColor(TFT_YELLOW, TFT_BLACK);
 tft.println("Rebooting in 3 seconds");
 delay(3000); 
 ESP.restart();
}

void handle_setClock() {
 //setup RTC
  RTCSetupTime();
  tft.fillScreen(TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_14); 
  tft.setCursor(0, 40);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  tft.println("Time set");
  tft.println("Rebooting in 3 seconds");
  delay(3000);
  ESP.restart();
}

void handle_setRemote() {
  String pon, poff, plow, phigh;

  preferences.begin("heaterctrl-app", false); 
  
  if (server.arg("pon") == ""){     //Parameter not found
     Serial.print("power on/pon/Argument not found");
  }else{     //Parameter found
    pon = server.arg("pon");
    Serial.print("poweron/pon = " + pon);
    preferences.putInt("PowerOnPin", pon.toInt());
  }

  if (server.arg("poff") == ""){     //Parameter not found
     Serial.print("power off/poff/Argument not found");
  }else{     //Parameter found
    poff = server.arg("poff");
    Serial.print("poweroff/poff = " + poff);
    preferences.putInt("PowerOffPin", poff.toInt());
  }
  
  if (server.arg("plow") == ""){     //Parameter not found
     Serial.print("hrz low/plow/Argument not found");
  }else{     //Parameter found
    plow = server.arg("plow");
    Serial.print("hrzlow/plow = " + plow);
    preferences.putInt("HzLowPin", plow.toInt());
  }

  if (server.arg("phigh") == ""){     //Parameter not found
     Serial.print("hrz high/phigh/Argument not found");
  }else{     //Parameter found
    phigh = server.arg("phigh");
    Serial.print("hrzhigh/phigh = " + phigh);
    preferences.putInt("HzHighPin", phigh.toInt());
  }
  
  if ((server.arg("pon") != "") && (server.arg("poff") != "") && (server.arg("plow") != "") && (server.arg("phigh") != "")){ 
    Serial.print("Remote GPIO Pins set");
    server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"30 ; url='/'\" /></head>Remote GPIO Pins set successfully, rebooting ctrlr. This page will refresh in 30 seconds.</html>");
    preferences.end();
    handle_reboot();
 }
 else{
  Serial.print("Error, gpio pins not set!");
  server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"5 ; url='/'\" /></head>ERROR: Remote GPIO Pins NOT set. This page will refresh in 5 seconds.</html>");
  preferences.end();
 }
}

void handle_setTimerOff() {
 int t,tsecs;	
 t = server.arg("timeoff").toInt();
 if (t != 0) {
  tsecs = (t * 60);
  timerSet = true;
  targTempSet = false;
  DateTime future (rtc.now() + TimeSpan(0,0,t,0));
  targYear = int(future.year());
  targMonth = int(future.month());
  targDay = int(future.day());
   
  targHour = int(future.hour());
  targMinute = int(future.minute());
  targUnix = rtc.now().unixtime() + tsecs;
  writeLongIntoEEPROM(100, targUnix);
  tft.fillScreen(TFT_BLACK);

  //draw background engine
  tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
  screen = "main";
  menuIndex=0;
  showMainMenu();
  server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"5 ; url='/'\" /></head>Success! Heater will turn off in "+String(tsecs)+" seconds. This page will refresh in 5 seconds.</html>");
 } else {
  tft.fillScreen(TFT_BLACK); 
  //draw background engine
  tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
  timerSet = false;
  targTempSet = false;
  screen = "main";
  menuIndex=0;
  showMainMenu(); 
  server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"5 ; url='/'\" /></head>Timer off. This page will refresh in 5 seconds.</html>");
 }
}

void handle_setTemperature() {
  int tempr;
  tempr = server.arg("t").toInt();
  if (tempr != 0) {
   targTemp = tempr;
   EEPROM.write(0, targTemp);
   EEPROM.commit();
   targTempSet=true;
   timerSet = false;
   tft.fillScreen(TFT_BLACK);
   //draw background engine
   tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
   screen = "main";
   tempSetMode="none";
   menuIndex=0;
   showMainMenu();
   server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"5 ; url='/'\" /></head>Success! Target temperature set to "+String(tempr)+"deg.C. This page will refresh in 5 seconds.</html>");
  } else {
   tft.fillScreen(TFT_BLACK);
   //draw background engine
   tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
   EEPROM.write(0, 0);
   EEPROM.commit();
   targTempSet=false;
   tempSetMode = "none";
   timerSet = false;
   screen = "main";
   menuIndex=0;
   showMainMenu();
   server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"5 ; url='/'\" /></head>Target temperature off/reset. This page will refresh in 5 seconds.</html>");
  }
}

void handle_frostMode() {
  int fmode;
  fmode = server.arg("f").toInt();
 if (fmode != 1) {
   tft.fillScreen(TFT_BLACK);
   //draw background engine
   tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
   EEPROM.write(0, 0);
   EEPROM.commit();
   targTempSet=false;
   tempSetMode = "none";
   timerSet = false;
   screen = "main";
   menuIndex=0;
   showMainMenu();
   server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"5 ; url='/'\" /></head>Frost mode off/reset. This page will refresh in 5 seconds.</html>");
 } else {
   targTemp = 41;
   EEPROM.write(0, targTemp);
   EEPROM.commit();
   targTempSet=true;
   timerSet = false;
   tft.fillScreen(TFT_BLACK);
   //draw background engine
   tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
   screen = "main";
   tempSetMode="none";
   menuIndex=0;
   showMainMenu();
   server.send(200, "text/html", "<html><head><meta http-equiv=\"refresh\" content=\"5 ; url='/'\" /></head>Success! Frost mode enabled. This page will refresh in 5 seconds.</html>");   
 }
}

void handle_heaterOFF() {  
 powerOff();
}

void handle_heaterON() {  
 powerOn();
}

void handle_heaterLOW() {  
  setLow();
}

void handle_heaterHIGH() {  
  setHigh();
}

//------------------------------------------------------------------------------------------------END WEB SERVER

void configModeCallback (WiFiManager *myWiFiManager) {
  //setup RTC
  RTCSetup();
  delay(2000);
  tft.fillScreen(TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_14); 
  tft.setCursor(0, 40);
  tft.println("Connect to SSID:");
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.println(myWiFiManager->getConfigPortalSSID());
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  tft.println("to config WiFi.");
  tft.println("AP IP:");
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.println(WiFi.softAPIP());
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  tft.drawBitmap(15, 140, cbclogo, 96, 68, TFT_RED);
}

void setup() { 
  Serial.begin(9600);

  //initialize and clear TFT
  tft.begin();
  tft.fillScreen(TFT_BLACK);
  tft.setFreeFont(&Lato_Heavy_12);
  
  tft.setCursor(0, 40);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  tft.println("WiFi...");
  
  //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around
    WiFiManager wm;
    wm.setConnectTimeout(90);
    wm.setAPCallback(configModeCallback);
    bool res;
    res = wm.autoConnect(); // password protected ap

    if(!res) {
        Serial.println("Failed to connect");
        tft.println("Failed to connect");
        wm.resetSettings();
        delay(2000);
        ESP.restart();
    } 
    else {
        //if you get here you have connected to the WiFi    
        Serial.println("connected! :)");
    }
  
  if (WiFi.status() == WL_CONNECTED) {
   tft.fillScreen(TFT_BLACK);
   tft.setCursor(0, 40); 
   tft.setFreeFont(&Lato_Heavy_12);
   Serial.println("Connecting to ");
   ssid = WiFi.SSID();
   Serial.println(ssid);
   Serial.println(WiFi.localIP());
   tft.println("Connected to:");
   tft.setTextColor(TFT_WHITE, TFT_BLACK);
   tft.println(ssid);
   tft.println(WiFi.localIP());
   delay(1000);

   /*handling uploading firmware file -----------------------------*/
   server.on("/firm", HTTP_GET, []() {
    String u = UP_page; //Read HTML contents
    server.sendHeader("Connection", "close");
    server.send(200, "text/html", u); //Send web page
   });
   server.on("/update", HTTP_POST, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
    ESP.restart();
   }, []() {
    HTTPUpload& upload = server.upload();
    if (upload.status == UPLOAD_FILE_START) {
      Serial.printf("Update: %s\n", upload.filename.c_str());
      if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_WRITE) {
      /* flashing firmware to ESP*/
      if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_END) {
      if (Update.end(true)) { //true to set the size to the current progress
        Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
      } else {
        Update.printError(Serial);
      }
    }
   });
   /*----------------------------------------------------------*/
   server.on("/", handle_OnConnect);
   server.on("/readDATA", handle_readDATA);
   server.on("/readPins", handle_readPins);
   server.on("/heaterOFF", handle_heaterOFF);
   server.on("/heaterON", handle_heaterON);
   server.on("/heaterLOW", handle_heaterLOW);
   server.on("/heaterHIGH", handle_heaterHIGH);
   server.on("/heaterReboot", handle_reboot);
   server.on("/heaterConfigWifi", handle_configWifi);
   server.on("/heaterSetClock", handle_setClock);
   server.on("/remoteSetPins", handle_setRemote);
   server.on("/setTimerOff", handle_setTimerOff);
   server.on("/setTemperature", handle_setTemperature);
   server.on("/setFrost", handle_frostMode);
   server.begin();

   tft.setTextColor(TFT_GREEN, TFT_BLACK);
   tft.println(" ");
   tft.println("Webserver ONLINE!");
   tft.drawBitmap(15, 120, checkm, 98, 86, TFT_GREEN);
  }
   
  WiFi.softAPdisconnect (true);

  delay(10000);

  //clear screen
  tft.fillScreen(TFT_BLACK);

  // initialize preferences storage
  preferences.begin("heaterctrl-app", false); 

  //obtain stored pin assignments for GPIO
  if (preferences.getInt("PowerOnPin", 0) != 0) {
    PowerOnPin = preferences.getInt("PowerOnPin", 0);
  }
  if (preferences.getInt("PowerOffPin", 0) != 0) {
    PowerOffPin = preferences.getInt("PowerOffPin", 0);
  }
  if (preferences.getInt("HzLowPin", 0) != 0) {
    HzLowPin = preferences.getInt("HzLowPin", 0);
  }
  if (preferences.getInt("HzHighPin", 0) != 0) {
    HzHighPin = preferences.getInt("HzHighPin", 0);
  }
  Serial.println("Retrieved GPIO pins: PowerOn:"+String(PowerOnPin)+ " PowerOff: "+String(PowerOffPin)+ " HrzLow: "+String(HzLowPin)+ " HrzHigh: "+String(HzHighPin));
  preferences.end();
  
  // initialize EEPROM with predefined size
  EEPROM.begin(0);

  // read the last states flash memory
  targTemp = EEPROM.read(0);
  if (targTemp > 0) {
    targTempSet = true;
  }
  targUnix = readLongFromEEPROM(100);
  if (targUnix != 0) {
    timerSet = true;
    DateTime n = DateTime(targUnix);
    targYear = int(n.year());
    targMonth = int(n.month());
    targDay = int(n.day());
    targHour = int(n.hour());
    targMinute = int(n.minute());
  }
  //Setup button inputs and attach interrupt functions
  pinMode(BUTTON1PIN, INPUT);
  pinMode(BUTTON2PIN, INPUT);
  attachInterrupt(BUTTON1PIN, toggleButton1, FALLING);
  attachInterrupt(BUTTON2PIN, toggleButton2, FALLING);

  //initialize HTU21D sensor
  myHTU.begin();
  
  //initialize DS3231 RTC
  RTCSetup();
  
  //setup battery-power
  /*
    ADC_EN is the ADC detection enable port
    If the USB port is used for power supply, it is turned on by default.
    If it is powered by battery, it needs to be set to high level
  */
  pinMode(POWEREN, OUTPUT);
  digitalWrite(POWEREN, HIGH);

  //setup remote ctrl pins
  pinMode(PowerOnPin, OUTPUT);
  pinMode(PowerOffPin, OUTPUT);
  pinMode(HzLowPin, OUTPUT);
  pinMode(HzHighPin, OUTPUT);
  digitalWrite(PowerOnPin, LOW);
  digitalWrite(PowerOffPin, LOW);
  digitalWrite(HzLowPin, LOW);
  digitalWrite(HzHighPin, LOW);
  
  //START MAIN MENU GUI
  //draw background engine
  tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
  
  //show main menu
  showMainMenu();
   
}
 

void loop() {
  //show main GUI
  if ((screen == "main") && (!targTempSet) && (!timerSet)) {
   tft.setTextColor(TFT_BLUE, TFT_BLACK);
   tft.setFreeFont(&Lato_Heavy_18);
   tft.setCursor(110, 11);     
   for(int c=1;c<=3;c++) {
     tft.print(".");
     delay(125);
   }
   showMain();
   tft.setTextColor(TFT_BLACK, TFT_BLACK);
   tft.setFreeFont(&Lato_Heavy_18);
   tft.setCursor(110, 11);     
   for(int c=1;c<=3;c++) {
     tft.print(".");
     delay(125);
   }
  }
  else if ((screen == "main") && (targTempSet)) {
   tft.setTextColor(TFT_BLUE, TFT_BLACK);
   tft.setFreeFont(&Lato_Heavy_18);
   tft.setCursor(110, 11);     
   for(int c=1;c<=3;c++) {
     tft.print(".");
     delay(125);
   }
   showAndMonitorTemperature();
   tft.setTextColor(TFT_BLACK, TFT_BLACK);
   tft.setFreeFont(&Lato_Heavy_18);
   tft.setCursor(110, 11);     
   for(int c=1;c<=3;c++) {
     tft.print(".");
     delay(125);
   }
  }
  else if ((screen == "main") && (timerSet)){
   tft.setTextColor(TFT_BLUE, TFT_BLACK);
   tft.setFreeFont(&Lato_Heavy_18);
   tft.setCursor(110, 11);     
   for(int c=1;c<=3;c++) {
     tft.print(".");
     delay(125);
   }
   showAndMonitorTime();
   tft.setTextColor(TFT_BLACK, TFT_BLACK);
   tft.setFreeFont(&Lato_Heavy_18);
   tft.setCursor(110, 11);     
   for(int c=1;c<=3;c++) {
     tft.print(".");
     delay(125);
   }
  }

  if (button2press) {
   if (screen == "main") {
    if (menuIndex == 4) {
      menuIndex = -1; 
    }
    menuIndex = menuIndex + 1;
    if (button2sel[menuIndex] == "on") {
    //main menu curson on power on
    //draw flame cursor at selection
    tft.drawBitmap(8, 215, flame, 24, 28, TFT_ORANGE);  
    //redraw off 
    tft.drawRect(90, 215, 40, 28, TFT_WHITE);
    tft.fillRect(92, 217, 37, 26, TFT_RED);
    tft.setTextColor(TFT_BLACK, TFT_RED);
    tft.setFreeFont(&Lato_Heavy_14);
    tft.setCursor(97, 235);
    tft.print("OFF");
    }
    else if (button2sel[menuIndex] == "high") {
      //main menu cursor on +/high
      //draw + font in ORANGE
      tft.setTextColor(TFT_WHITE, TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_14);
      tft.setCursor(48, 235);
      tft.print("+"); 
      //redraw on 
      tft.drawRect(0, 215, 40, 28, TFT_WHITE);
      tft.fillRect(2, 217, 37, 26, TFT_GREEN);
      tft.setTextColor(TFT_BLACK, TFT_GREEN);
      tft.setFreeFont(&Lato_Heavy_14);
      tft.setCursor(9, 235);
      tft.print("ON");
    }
    else if (button2sel[menuIndex] == "sub_menu") {
      //main menu cursor on goto submenu
      //draw flame cursor at middle selection
      tft.drawBitmap(53, 215, flame, 24, 28, TFT_ORANGE);  
      //redraw +
      tft.setTextColor(TFT_GREEN, TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_14);
      tft.setCursor(48, 235);
      tft.print("+"); 
    }
    else if (button2sel[menuIndex] == "low") {
      //main menu cursor on -/low
      //draw - in orange font
      tft.setTextColor(TFT_WHITE, TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_14);
      tft.setCursor(75, 235);
      tft.print("-");
      //redraw sub-menu 
      tft.drawBitmap(53, 215, flame, 24, 28, TFT_BLACK);  
      tft.drawLine(58, 226, 72, 226, TFT_WHITE);
      tft.drawLine(58, 231, 72, 231, TFT_WHITE);
      tft.drawLine(58, 236, 72, 236, TFT_WHITE);
    }
    else if (button2sel[menuIndex] == "off") {
      //main menu cursor on power off
      //draw flame cursor at selection
      tft.drawBitmap(98, 215, flame, 24, 28, TFT_ORANGE);  
      //redraw -
      tft.setTextColor(TFT_RED, TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_14);
      tft.setCursor(75, 235);
      tft.print("-");
    }  
   }
   else if (screen == "sub") {
    if (menuIndex == 7) {
      menuIndex = 4; 
    }
    menuIndex = menuIndex + 1;
    if (button2sel[menuIndex] == "temp_menu") {
    tft.fillScreen(TFT_BLACK);
    tft.setTextColor(TFT_YELLOW, TFT_BLACK);
    tft.setFreeFont(&Lato_Heavy_28);
    tft.setCursor(0, 90);
    tft.println("[-]TEMP");
    tft.setTextColor(0x8410, TFT_BLACK);  //set inactive items gray
    tft.println("[ ]TIMER");
    tft.println("[ ]BACK");
    }
    else if (button2sel[menuIndex] == "timer_menu") {
     tft.fillScreen(TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_28);
     tft.setCursor(0, 90);
     tft.setTextColor(0x8410, TFT_BLACK);
     tft.println("[ ]TEMP");
     tft.setTextColor(TFT_YELLOW, TFT_BLACK);
     tft.println("[-]TIMER");
     tft.setTextColor(0x8410, TFT_BLACK);
     tft.println("[ ]BACK");
    }
    else if (button2sel[menuIndex] == "back") {
     tft.fillScreen(TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_28);
     tft.setCursor(0, 90);
     tft.setTextColor(0x8410, TFT_BLACK);
     tft.println("[ ]TEMP");
     tft.println("[ ]TIMER");
     tft.setTextColor(TFT_YELLOW, TFT_BLACK);
     tft.println("[-]BACK");
    }
   }
   else if (screen == "temperature") {
    if (menuIndex == 11) {
      menuIndex = 7; 
    }
    menuIndex = menuIndex + 1;
    if (button2sel[menuIndex] == "temp_down") {
     tft.fillTriangle(20,240,0,200,40,200,TFT_BLUE);
     tft.fillTriangle(110,200,90,240,130,240,0x8410);
     tft.fillRect(54,200,30,18,0x8410);
     tft.fillRect(54,221,30,18,0x8410);
     tft.setTextColor(TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_12);
     tft.setCursor(58,215);
     tft.println("OK"); 
     tft.setCursor(57,235);
     tft.println("Bck"); 
    }
    else if (button2sel[menuIndex] == "ok") {
     tft.fillTriangle(20,240,0,200,40,200,0x8410);
     tft.fillRect(54,200,30,18,TFT_YELLOW);
     tft.fillRect(54,221,30,18,0x8410);
     tft.setTextColor(TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_12);
     tft.setCursor(58,215);
     tft.println("OK"); 
     tft.setCursor(57,235);
     tft.println("Bck");
    }
    else if (button2sel[menuIndex] == "back") {
     tft.fillTriangle(20,240,0,200,40,200,0x8410);
     tft.fillRect(54,200,30,18,0x8410);
     tft.fillRect(54,221,30,18,TFT_YELLOW);
     tft.setTextColor(TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_12);
     tft.setCursor(58,215);
     tft.println("OK"); 
     tft.setCursor(57,235);
     tft.println("Bck");
    }
    else if (button2sel[menuIndex] == "temp_up") {
     tft.fillTriangle(110,200,90,240,130,240,TFT_RED);
     tft.fillRect(54,221,30,18,0x8410);
     tft.setTextColor(TFT_BLACK);
     tft.setFreeFont(&Lato_Heavy_12);
     tft.setCursor(58,215);
     tft.println("OK"); 
     tft.setCursor(57,235);
     tft.println("Bck");
    }
   }
   else if (screen == "timer") {
    if (menuIndex == 17) {
      menuIndex = 11; 
    }
    menuIndex = menuIndex + 1;
    if (button2sel[menuIndex] == "five") {
      tft.fillScreen(TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_28);
      tft.setCursor(0, 40);
      tft.setTextColor(TFT_YELLOW, TFT_BLACK);
      tft.println("[-]5 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]20 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]40 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]60 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]120 Mn");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]BACK");
    }
    else if (button2sel[menuIndex] == "twenty") {
      tft.fillScreen(TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_28);
      tft.setCursor(0, 40);
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]5 Min");
      tft.setTextColor(TFT_YELLOW, TFT_BLACK);
      tft.println("[-]20 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]40 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]60 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]120 Mn");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]BACK");
    }
    else if (button2sel[menuIndex] == "forty") {
      tft.fillScreen(TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_28);
      tft.setCursor(0, 40);
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]5 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]20 Min");
      tft.setTextColor(TFT_YELLOW, TFT_BLACK);
      tft.println("[-]40 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]60 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]120 Mn");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]BACK");
    }
    else if (button2sel[menuIndex] == "1hour") {
      tft.fillScreen(TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_28);
      tft.setCursor(0, 40);
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]5 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]20 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]40 Min");
      tft.setTextColor(TFT_YELLOW, TFT_BLACK);
      tft.println("[-]60 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]120 Mn");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]BACK");
    }
    else if (button2sel[menuIndex] == "2hour") {
      tft.fillScreen(TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_28);
      tft.setCursor(0, 40);
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]5 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]20 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]40 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]60 Min");
      tft.setTextColor(TFT_YELLOW, TFT_BLACK);
      tft.println("[-]120 Mn");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]BACK");
    }
    else if (button2sel[menuIndex] == "back") {
      tft.fillScreen(TFT_BLACK);
      tft.setFreeFont(&Lato_Heavy_28);
      tft.setCursor(0, 40);
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]5 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]20 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]40 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]60 Min");
      tft.setTextColor(0x8410, TFT_BLACK);
      tft.println("[ ]120 Mn");
      tft.setTextColor(TFT_YELLOW, TFT_BLACK);
      tft.println("[-]BACK");
    }
    }
   button2press=false;  
 }

  if (button1press) {
    if (screen == "main") {
      if (button2sel[menuIndex] == "on") {
       screen = "power_on"; 
       powerOn();
       menuIndex=0;
      }
      else if (button2sel[menuIndex] == "high") {
       screen = "high";
       setHighGUI(); 
       menuIndex=0;
      }
      else if (button2sel[menuIndex] == "sub_menu") {
       menuIndex=5;
       screen = "sub";
       sub_main(); 
      }
      else if (button2sel[menuIndex] == "low") {
       screen = "low";
       setLowGUI(); 
       menuIndex=0;
      }
      else if (button2sel[menuIndex] == "off") {
       screen = "power_off";
       powerOff(); 
       menuIndex=0;
      }
    }
    else if (screen == "sub") {
      if (button2sel[menuIndex] == "temp_menu") {
        menuIndex = 8;
        screen ="temperature";
        temperatureSet();
      }
      else if (button2sel[menuIndex] == "back") {
       tft.fillScreen(TFT_BLACK);
       tft.setSwapBytes(false);
       //draw background engine
       tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
       screen = "main";
       menuIndex=0;
       showMainMenu();
      }
      else if (button2sel[menuIndex] == "timer_menu") {
        menuIndex = 12;
        screen ="timer";
        timerSetGUI();
      }
    } 
    else if (screen == "temperature") {
      if (button2sel[menuIndex] == "temp_down") {
       //write current value black to clear then write new temp value to display
       tft.setTextColor(TFT_BLACK, TFT_WHITE);
       tft.setFreeFont(&Lato_Heavy_46);
       tft.setCursor(41, 150);
       tft.println(targTemp);
       tft.setTextColor(TFT_WHITE, TFT_BLACK);
       tft.setFreeFont(&Lato_Heavy_46);
       tft.setCursor(41, 150);
       targTemp = targTemp-1;
       tft.println(targTemp);
      }
      else if (button2sel[menuIndex] == "ok") {
        EEPROM.write(0, targTemp);
        EEPROM.commit();
        targTempSet=true;
        timerSet = false;
        tft.fillScreen(TFT_BLACK);
        //draw background engine
        tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
        screen = "main";
        tempSetMode="none";
        menuIndex=0;
        showMainMenu();
      }
      else if (button2sel[menuIndex] == "back") {
        tft.fillScreen(TFT_BLACK);
        //draw background engine
        tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
        EEPROM.write(0, 0);
        EEPROM.commit();
        targTempSet=false;
        tempSetMode = "none";
        timerSet = false;
        screen = "main";
        menuIndex=0;
        showMainMenu();
      }
      else if (button2sel[menuIndex] == "temp_up") {
        //write current value black to clear then write new temp value to display
        tft.setTextColor(TFT_BLACK, TFT_WHITE);
        tft.setFreeFont(&Lato_Heavy_46);
        tft.setCursor(41, 150);
        tft.println(targTemp);
        tft.setTextColor(TFT_WHITE, TFT_BLACK);
        tft.setFreeFont(&Lato_Heavy_46);
        tft.setCursor(41, 150);
        targTemp = targTemp+1;
        tft.println(targTemp);
      }
    }
    else if (screen == "timer") {
      if (button2sel[menuIndex] == "five") {
       timerSet = true;
       targTempSet = false;
       DateTime future (rtc.now() + TimeSpan(0,0,5,0));
       targYear = int(future.year());
       targMonth = int(future.month());
       targDay = int(future.day());
       
       targHour = int(future.hour());
       targMinute = int(future.minute());
       targUnix = rtc.now().unixtime() + 240;
       writeLongIntoEEPROM(100, targUnix);
       tft.fillScreen(TFT_BLACK);
       //draw background engine
       tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
       screen = "main";
       menuIndex=0;
       showMainMenu();
      }
      if (button2sel[menuIndex] == "twenty") {
       timerSet = true;
       DateTime future (rtc.now() + TimeSpan(0,0,20,0));
       targYear = int(future.year());
       targMonth = int(future.month());
       targDay = int(future.day());
       if ((mymonth >=3) && (mymonth <= 10)) {
          targHour = int(future.hour())+1;
       }
       else {
          targHour = int(future.hour());
       }
       targMinute = int(future.minute());
       targUnix = rtc.now().unixtime() + 1140;
       timerSet = true;
       targTempSet = false;
       writeLongIntoEEPROM(100, targUnix);
       tft.fillScreen(TFT_BLACK);
       //draw background engine
       tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
       screen = "main";
       menuIndex=0;
       showMainMenu();
      }
      if (button2sel[menuIndex] == "forty") {
       DateTime future (rtc.now() + TimeSpan(0,0,40,0));
       targYear = int(future.year());
       targMonth = int(future.month());
       targDay = int(future.day());
       if ((mymonth >=3) && (mymonth <= 10)) {
          targHour = int(future.hour())+1;
       }
       else {
          targHour = int(future.hour());
       }
       targMinute = int(future.minute());
       targUnix = rtc.now().unixtime() + 2340;
       timerSet = true;
       targTempSet = false;
       writeLongIntoEEPROM(100, targUnix);
       tft.fillScreen(TFT_BLACK);
       //draw background engine
       tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
       screen = "main";
       menuIndex=0;
       showMainMenu();
      }
      if (button2sel[menuIndex] == "1hour") {
       DateTime future (rtc.now() + TimeSpan(0,1,0,0));
       targYear = int(future.year());
       targMonth = int(future.month());
       targDay = int(future.day());
       if ((mymonth >=3) && (mymonth <= 10)) {
          targHour = int(future.hour())+1;
       }
       else {
          targHour = int(future.hour());
       }
       targMinute = int(future.minute());
       targUnix = rtc.now().unixtime() + 3540; 
       timerSet = true;
       targTempSet = false;
       writeLongIntoEEPROM(100, targUnix);
       tft.fillScreen(TFT_BLACK);
       //draw background engine
       tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
       screen = "main";
       menuIndex=0;
       showMainMenu();
      }
      if (button2sel[menuIndex] == "2hour") {
       DateTime future (rtc.now() + TimeSpan(0,2,0,0));
       targYear = int(future.year());
       targMonth = int(future.month());
       targDay = int(future.day());
       if ((mymonth >=3) && (mymonth <= 10)) {
          targHour = int(future.hour())+1;
       }
       else {
          targHour = int(future.hour());
       }
       targMinute = int(future.minute());
       targUnix = rtc.now().unixtime() + 7140;
       timerSet = true;
       targTempSet = false;
       writeLongIntoEEPROM(100, targUnix);
       tft.fillScreen(TFT_BLACK);
       //draw background engine
       tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
       screen = "main";
       menuIndex=0;
       showMainMenu();
      }
      else if (button2sel[menuIndex] == "back") {
       tft.fillScreen(TFT_BLACK);
       tft.setSwapBytes(false);
       //draw background engine
       tft.drawBitmap(0, 0, engine, 130, 240, TFT_WHITE);
       writeLongIntoEEPROM(100, 0);
       screen = "main";
       timerSet = false;
       targTempSet = false;
       menuIndex=0;
       showMainMenu();
      }
    }
    button1press=false;
  }
  
  server.handleClient();
  delay(100);

}

On the HTML input form, include a password input field. The contents of that field can then be retrieved through the HTML POST array and you can have your code check whether the input was correct.

This was not included in the code you posted, so I don't know what the root web page looks like. Anyway, this is the one where you'd have to include the password field.

const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<title>Diesel Heater Controller - Caschy</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  <link rel='icon' href='data:image/png;base64,Qk1YCgAAAAAAADYAAAAoAAAAGAAAACQAAAABABgAAAAAACIKAAASCwAAEgsAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoKWVlZPj4+Dw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMTExMTAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQELS0tW1tbdHR0KCgoBQUFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ0NDZ2dnLCwsAAAAAAAAAAAAAAAAAAAADAwMKysrhoaGzc3NZWVlDg4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS0tLhYWFYWFhNDQ0AgICAAAAAAAAAAAALi4ugYGB29vb/v7+TU1NBwcHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANjY2kZGRra2tdHR0ISEhBQUFAAAAFRUVZ2dn3Nzc////7OzsVVVVCgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBNzc3wsLC////jo6OXV1dFxcXAAAAWFhY0NDQ/f39////8PDwbGxsERERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoKR0dHurq6////9vb2mJiYIiIiAAAAdnZ25OTk////////8vLyg4ODExMTAAAAAAAAAAAAAAAAAAAAAAAAAQEBAgICAAAAOTk5rq6u7+/v////////lpaWLS0tEBAQf39/4uLi////////8vLygYGBLCwsCQkJAAAAAAAAAAAAAAAAAAAABgYGCQkJAAAAWFhY3t7e////////////09PTZWVlLCwsf39/4uLi////////9/f3srKyYGBgEhISBQUFEhISAAAAAAAAAAAAEhISKSkpCwsLWFhY09PT////////////////kZGRPz8/fn5+4uLi////////////////ioqKDg4OFRUVUVFRDg4OAgICAAAAHh4eXV1dYGBgeHh41NTU////////////////jIyMQEBAeXl54ODg////////////////g4ODBwcHICAghoaGXl5eEhISAAAAFxcXf39/9/f3+vr6/v7+////////////////hoaGNzc3bW1t6Ojo////////////////gICAOjo6UFBQc3NzdXV1FxcXAAAADw8PcHBw/////////////////////v7+srKyTk5OJiYmTExMlpaW4ODg////////////0NDQwcHByMjIx8fHz8/PR0dHAAAACwsLbm5u/f39/////////////////f39mJiYKioqCwsLHBwcTk5Oy8vL////////////////////////////////ampqAAAAEBAQhISE/f39////////////////////nZ2dISEhAAAAAAAARkZGu7u78/Pz/f394+Pj3Nzc4uLi8/Pz////////XV1dAgICIiIilpaW/f39/////////////Pz86enphYWFHBwcAAAAAAAALCwsXl5etra29fX1UVFRHBwcRkZGs7Oz////////V1dXJCQkUFBQlJSU/f39////////////6enpfn5+Tk5OExMTAAAAAAAABwcHOjo6urq69fX1Tk5OAAAALy8vsrKy////////4ODg2NjY4ODg6+vr////////////////6+vre3t7GxsbAwMDAAAAAAAAAAAAKCgotra2////UVFRAAAALy8vtLS0////////////////////////////////////////9fX1bGxsCgoKAAAAAAAAAAAAAAAAHBwciIiIzMzMPT09AAAAMjIytbW1////////////////9vb2yMjIwcHBv7+/7u7u9fX1s7OzQkJCBwcHAAAAAAAAAAAAAAAAERERU1NTfHx8HR0dAAAANjY2t7e3////////////8vLyvLy8VVVVMTExQUFB09PT5eXlV1dXFhYWAgICAAAAAAAAAAAAAAAABgYGS0tLg4ODCAgIAAAAOjo6uLi4////////////tra2Y2NjQEBAAAAAPj4+1dXV5ubmW1tbAAAAAAAAAAAAAAAAAAAAAAAAGRkZTk5OVVVVAwMDEhISRUVFra2t////////////xcXFRUVFCQkJAAAAPT09g4ODl5eXX19fAAAAAAAAAAAAAAAAAAAAAAAAGBgYLCwsFRUVAAAAIyMjk5OT4+Pj////////yMjIcXFxGRkZAAAAAAAAExMTWlpajY2NW1tbAAAAAAAAAAAAAAAAAAAAAAAACQkJCAgIAAAAAAAAMTExxMTE////////////m5ubKCgoAAAAAAAAAAAAAAAAPj4+i4uLaGhoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOzs7wcHB/////Pz85ubmfHx8FhYWAAAAAAAAAAAAAAAAGBgYXV1dcHBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/w8PD////8PDwhYWFLy8vBAQEAAAAAAAAAAAAAAAAAAAAJCQkTExMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPj4+w8PD////8PDwgoKCGRkZAAAAAAAAAAAAAAAAAAAAAAAABAQECgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODg4v7+/////7u7uc3NzERERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKSkpvb29////6urqXV1dDQ0NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMTk5OT8fHx6+vrTU1NCQkJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8v7+/8/PzRkZGBwcHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzvr6++vr6R0dHBgYGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMTb29vsbGxTU1NCwsLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKioqdHR0ampqFhYWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ0NREREd3d3GxsbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMVlZWFRUVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=' type='image/x-png' /> <meta charset="utf-8">
 <style type="text/css">
 	@import url('https://fonts.googleapis.com/css?family=Muli:300,400,600,700&display=swap');
 	body{
 		background: #F1F0F0;
 		font-family: 'Muli', sans-serif;
 	}
 	.fa{
 		color: #CCCCCC;
 		text-align: center;
 		padding: 30px;
 		font-size: 46px;
 	}
 	.card{
 		padding: 15px;
 		margin: 10px;
 		 box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.01);
    transition: box-shadow 0.3s ease-in-out;
    border:1px solid #ddd;
    cursor: pointer;
    border-radius: 4px;
 	}
 	.card:hover{
 		box-shadow: 0 5px 15px 2px rgba(0, 0, 0, 0.3);
 	}
 	h3{
 		text-align: center;
 		font-size: 22px;
 		color: #839192;
    font-weight: 600;

 	}

  h4{
    padding: 5px;
    text-align: center;
    font-size: 15px;
    line-height: 1.6;
    font-weight: 500;
    padding-top: 5px;
  }
  
 	p{
 		padding: 5px;
 		text-align: center;
 		font-size: 15px;
 		color: #839192;
 		line-height: 1.6;
    font-weight: 500;
    padding-top: 5px;
   
 	}
	.switch {
		position: relative;
		display: inline-block;
		width: 60px;
		height: 34px;
	}

	.switch input { 
		opacity: 0;
		width: 0;
		height: 0;
	}

	.slider {
		position: absolute;
		cursor: pointer;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: #ccc;
		-webkit-transition: .4s;
		transition: .4s;
	}

	.slider:before {
		position: absolute;
		content: "";
		height: 26px;
		width: 26px;
		left: 4px;
		bottom: 4px;
		background-color: white;
		-webkit-transition: .4s;
		transition: .4s;
	}

	input:checked + .slider {
		background-color: #2196F3;
	}

	input:focus + .slider {
		box-shadow: 0 0 1px #2196F3;
	}

	input:checked + .slider:before {
		-webkit-transform: translateX(26px);
		-ms-transform: translateX(26px);
		transform: translateX(26px);
		}

	/* Rounded sliders */
	.slider.round {
		border-radius: 34px;
	}

	.slider.round:before {
		border-radius: 50%;
	}
	
	/*fade text*/
	@keyframes flickerAnimation {
		0%   { opacity:1; }
		50%  { opacity:0; }
		100% { opacity:1; }
	}
	
	@-o-keyframes flickerAnimation{
		0%   { opacity:1; }
		50%  { opacity:0; }
		100% { opacity:1; }
	}

	@-moz-keyframes flickerAnimation{
		0%   { opacity:1; }
		50%  { opacity:0; }
		100% { opacity:1; }
	}

	@-webkit-keyframes flickerAnimation{
		0%   { opacity:1; }
		50%  { opacity:0; }
		100% { opacity:1; }
	}

	.animate-flicker {
		-webkit-animation: flickerAnimation 1s infinite;
		-moz-animation: flickerAnimation 1s infinite;
		-o-animation: flickerAnimation 1s infinite;
		animation: flickerAnimation 1s infinite;
	}
 </style>
</head>
<body>

<div class="container mt-4" >
  <h1 class="text-center pb-3">Diesel Heater Remote Controller</h1>
  <div class="row">
  	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
	<div class="col-lg-3 col-md-6 col-xs-12 pl-1 pr-1">
  		<div class="card">
  		<i class="fa fa-cog"></i>
  		<h3>Ctrlr Setup</h3>
  		<a onClick="getReq('/heaterReboot');" class="btn btn-secondary">Reboot Ctrlr</a>
		  <br>
		  <a onClick="getReq('/heaterConfigWifi');" class="btn btn-light">Config Wifi</a>
		  <br>
      <a onclick="window.dialog.showModal();" class="btn btn-info">Set Clock</a>
      <br>
		  <a onclick="window.dialogg.showModal(); getPins();" class="btn btn-primary">Config Remote</a>
      <br>
      <a href="/firm" class="btn btn-warning">Firmware</a>
		  </div>
  	</div>
	<dialog id="dialog">
		<h6>Set Time(24hr):</h6>
		<form action="/heaterSetClock" method="get">
	    <p>Hour:
		<input type="number" id="hr" name="hr" min="0" max="23" value="0">
		&nbsp;Minutes:
		<input type="number" id="min" name="min" min="0" max="59" value="0">
		</p>
		<h6>Set Date:</h6>
		<p>Month:
		<input type="number" id="mon" name="mon" min="1" max="12" value="1">
		&nbsp;Day:
		<input type="number" id="day" name="day" min="1" max="31" value="1">
		&nbsp;Year:
		<input type="number" id="yr" name="yr" min="2023" max="2042" value="2023">
		</p>
		
		<input type="submit" value="Save">
		</form>
		<br>
		<form method="dialog">
			<button>Cancel</button>
		</form>
	</dialog>
   <dialog id="dialogg">
    <h6>Set Buttons:</h6>
    <form action="/remoteSetPins" method="get">
      <p>Power ON:
      <input type="number" id="PowerOnPValue" name="pon" value="" maxlength="2" size="2" disabled>
      &nbsp;Power OFF:
      <input type="number" id="PowerOffPValue" name="poff" value="" maxlength="2" size="2" disabled>
      </p>
      <p>LOW:
      <input type="number" id="HzLowPValue" name="plow" value="" maxlength="2" size="2" disabled>
      &nbsp;HIGH:
      <input type="number" id="HzHighPValue" name="phigh" value="" maxlength="2" size="2" disabled>
      </p>
      <input type="submit" value="Save">
    </form>
    <br>
    <form method="dialog">
      <button>Cancel</button>
    </form>
   </dialog>
   <dialog id="dialoggg">
    <h6>Set Timer Off in:</h6>
    <form action="/setTimerOff" method="get" id="timeoffx">
	   <select name="timeoff" id="timeoff" form="timeoffx">
		  <option value="0">Reset</option>
		  <option value="5">5 mins</option>
		  <option value="20" selected>20 mins</option>
		  <option value="40">40 mins</option>
		  <option value="60">1 hour</option>
		  <option value="120">2 hours</option>
	   </select>
      <input type="submit" value="Set">
    </form>
    <br>
    <form method="dialog">
      <button>Cancel</button>
    </form>
   </dialog>
   <dialog id="dialogggg">
		<h6>Set Temperature(°C):</h6>
		<form action="/setTemperature" method="get">
	    <input type="number" id="settemp" name="t" min="4" max="26" value="4">
		<input type="submit" value="Set">
		</form>
    <br>
		<form action="/setTemperature" method="get">
	    <input type="hidden" id="settemp" name="t" value="0">
		<input type="submit" value="Reset">
		</form>
		<br>
		<form method="dialog">
			<button>Cancel</button>
		</form>
	</dialog>
	<dialog id="dialoggggg">
		<h6>Toggle Frost Mode:</h6>
		<form action="/setFrost" method="get" id="frostmode">
	    <label class="switch">
		 <input type="hidden" name="f" value="0"><input type="checkbox" onclick="this.previousSibling.value=1-this.previousSibling.value">
		 <span class="slider round"></span>
		</label>
		<input type="submit" value="Set">
		</form>
		<br>
		<form method="dialog">
			<button>Cancel</button>
		</form>
	</dialog>
	<div class="col-lg-5 col-md-6 col-xs-11 pl-1 pr-1">
  		<div class="card">
  		<i class="fa fa-stack-overflow"></i>
  		<h3>Heater Stats</h3>
  		<h5>Time: <span id="TIMEValue"></span>&nbsp;&nbsp;Temp: <span id="TEMPFValue"></span>&deg;C&nbsp;Bat: <span id="BATValue"></span>V&nbsp;&nbsp;Hum: <span id="HUMValue"></span>%</h5>
		<span id="MOREValue" style="color:red;"></span>
		<select name="history" id="history">
			<option value="history">History</option>
		</select>
		<p>polling every <input type="number" id="intv" value="10" min="10"/> seconds</p>
  	</div>
  	</div>
  	
  	<div class="col-lg-3 col-md-6 col-xs-12 pl-1 pr-1">
  		<div class="card">
  		<i class="fa fa-puzzle-piece"></i>
  		<h3>Heater Control</h3>
		<a onClick="getReq('/heaterOFF');" class="btn btn-danger">HEATER OFF</a>
		<a onClick="getReq('/heaterON');" class="btn btn-success">HEATER ON</a>
		<br>
		<a onClick="getReq('/heaterLOW');" class="btn btn-primary">HEATER LOW</a>
		<a onClick="getReq('/heaterHIGH');" class="btn btn-warning">HEATER HIGH</a>
		<br>
		<a onclick="window.dialogggg.showModal();" class="btn btn-secondary">Set Targ Temperature</a>
		<a onclick="window.dialoggg.showModal();" class="btn btn-info">Set Off in X Minutes</a>
    <br>
    <a onclick="window.dialoggggg.showModal();" class="btn btn-light">Frost Mode</a>
  	</div>
  	</div>

  </div>    
</div>


<hr>
<center>
<div id="chart-temperature" class="container" style="display: inline-block; width: 50%;"></div><div id="chart-hum" class="container" style="display: inline-block; width: 50%;" ></div>

</div>
</center>

<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>

<script>
var chartT = new Highcharts.Chart({
  chart:{ renderTo : 'chart-temperature' },
  title: { text: 'Ambient Temperature' },
  series: [{
    showInLegend: false,
    data: []
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    },
    series: { color: '#059e8a' }
  },
  //xAxis: { type: 'string'
    //dateTimeLabelFormats: { second: '%b/%D %H:%M' }
  //},
  yAxis: {
    title: { text: 'Temperature (Celsius)' }
    //title: { text: 'Temperature (Fahrenheit)' }
  },
  credits: { enabled: false }
});

var chartH = new Highcharts.Chart({
  chart:{ renderTo : 'chart-hum' },
  title: { text: 'Humidity' },
  series: [{
    showInLegend: false,
    data: []
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    },
    series: { color: '#079e8a' }
  },
  //xAxis: { type: 'string'
    //dateTimeLabelFormats: { second: '%b/%D %H:%M' }
  //},
  yAxis: {
    //title: { text: 'Temperature (Celsius)' }
    title: { text: 'Humidity (%)' }
  },
  credits: { enabled: false }
});

function getReq(theUrl) {
    var xchttp = new XMLHttpRequest();
    xchttp.open( "GET", theUrl, false ); // false for synchronous request
    xchttp.send(null);
}

function getData() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var respon = this.responseText.split("|");
      document.getElementById("TEMPFValue").innerHTML = respon[0];
      document.getElementById("TIMEValue").innerHTML = respon[1];
      document.getElementById("BATValue").innerHTML = respon[2];
      document.getElementById("HUMValue").innerHTML = respon[3];
      let isnum = /^\d+$/.test(respon[4]);
      if (isnum) {
       document.getElementById("MOREValue").innerHTML = "<h4 class=\"animate-flicker\">"+respon[4]+"&deg;C target set</h4>";
      }
       else if (respon[4] == " ") {
        document.getElementById("MOREValue").innerHTML = "";
      }
       else {
        document.getElementById("MOREValue").innerHTML = "<h4 class=\"animate-flicker\">"+respon[4]+" target time set</h4>";
       }
      var select = document.getElementById("history");
      var option = document.createElement('option');
      option.text = option.value = respon[1] + " -- " + respon[0] + " -- " + respon[2] + " -- " + respon[3];
      select.add(option, 0);

      var d = new Date();
      var dd = d.toJSON().substring(0,10);
      var x = dd + " " + respon[1];
      var y = parseFloat(respon[0]);
      //console.log(this.responseText);
      if(chartT.series[0].data.length > 40) {
        chartT.series[0].addPoint([x, y], true, true, true);
      } else {
        chartT.series[0].addPoint([x, y], true, false, true);
      }
      var x = dd + " " + respon[1];
      var y = parseInt(respon[3]);
      if(chartH.series[0].data.length > 40) {
        chartH.series[0].addPoint([x, y], true, true, true);
      } else {
        chartH.series[0].addPoint([x, y], true, false, true);
      }
    }
  };
  xhttp.open("GET", "readDATA", true);
  xhttp.send();
}

function getPins() {
 $("#PowerOnPValue").prop("disabled", false);
 $("#PowerOffPValue").prop("disabled", false);
 $("#HzLowPValue").prop("disabled", false);
 $("#HzHighPValue").prop("disabled", false);
 var xhttp = new XMLHttpRequest();
  xhttp.onload = function() {
    if (this.readyState == 4 && this.status == 200) {
      var respon = this.responseText.split("|");
      document.getElementById("PowerOnPValue").value = respon[0];
      document.getElementById("PowerOffPValue").value = respon[1];
      document.getElementById("HzLowPValue").value = respon[2];
      document.getElementById("HzHighPValue").value = respon[3];
    }
  };
  xhttp.open("GET", "readPins", true);
  xhttp.send();
}

 
var interval;
var t;

f1();

function f1() {
 t = document.getElementById("intv").value;
 t = t * 1000;
 clearInterval(interval);
 getData();
 interval = setInterval(f1, t);
}

</script>
<br>
</body>
</html>
)=====";

Yes, so that's where you could insert a password field. Since there are actually multiple forms, you could consider using a single password field and then use JavaScript to include its value into each form upon submission.

If you're new to programming, I'd suggest starting with a much simpler setup especially on the html side.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.