/*
    LilyGo Ink Screen Series Test
        - Created by Lewis he
*/
//058:BF:25:05:AF:98

// According to the board, cancel the corresponding macro definition
// #define LILYGO_T5_V213
// #define LILYGO_T5_V22
 #define LILYGO_T5_V24
// #define LILYGO_T5_V28
// #define LILYGO_T5_V102
// #define LILYGO_T5_V266
// #define LILYGO_EPD_DISPLAY_102      //Depend  https://github.com/adafruit/Adafruit_NeoPixel
// #define LILYGO_EPD_DISPLAY_154

#include <boards.h>
#include <GxEPD.h>
#include <SD.h>
#include <FS.h>
#include <Wire.h>
#include "Adafruit_HTU21DF.h"
Adafruit_HTU21DF htu = Adafruit_HTU21DF();


 #include <GxDEPG0290R/GxDEPG0290R.h>      // 2.9" b/w/r  form DKE GROUP
#include <Arduino.h>            // In-built
#include <esp_task_wdt.h>       // In-built
#include "esp_adc_cal.h"        // In-built
#include "owm_credentials.h"
#include "forecast_record.h"
#include "lang.h"

#include GxEPD_BitmapExamples
#include "im1.h"
#include "im2.h"
// FreeFonts from Adafruit_GFX
//#include <Fonts/FreeMonoBold9pt7b.h>
//#include <Fonts/FreeMonoBold12pt7b.h>
//#include <Fonts/FreeMonoBold18pt7b.h>
//#include <Fonts/FreeMonoBold24pt7b.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>

#include <ArduinoJson.h>        // https://github.com/bblanchon/ArduinoJson
#include <HTTPClient.h>         // In-built
#include <time.h>               // In-built
#include <esp_now.h>
#include <esp_wifi.h>
#include <WiFi.h>

#include "NTPClient.h"
#include "WiFiUdp.h"
#include <UnixTime.h>

#define BUTTON_PIN_BITMASK 0xE000000000 // 2^37+2^38+2^39 in hex маска кнопок RTC для пробуждения
UnixTime stamp(0);  // указать GMT (3 для Москвы)
//#include <SD.h>
//const char* ssid     = "VOVA-47";
//const char* password = "vovak26102003";
GxIO_Class io(SPI,  EPD_CS, EPD_DC,  EPD_RSET);
GxEPD_Class display(io, EPD_RSET, EPD_BUSY);
bool rlst;
bool p=0;//флаг подстраницы page4
bool now1=0;
uint32_t start_time;
uint32_t next_time;
uint32_t previous_time;
uint32_t previous_full_update;

uint32_t total_seconds = 0;
uint32_t seconds, minutes, hours, days;
const uint32_t partial_update_period_s = 1;
const uint32_t full_update_period_s = 6 * 60 * 60;
//**********************************************************************************
//08:3A:F2:A7:80:6C //esp32 желтые ноги
//08:3A:F2:66:31:30 //esp32 lilygo2,3
//08:3A:F2: //esp32 lilygo4,7
//EC:94:CB:6C:EC:A4  esp32 самоделка
#define BOARD_ID 2
uint8_t broadcastAddress1[] = {0x8, 0x3A, 0xF2, 0xA7, 0x80, 0x6C};//esp32 желтые ноги
uint8_t broadcastAddress2[] = {0xEC, 0x94, 0xCB, 0x6C, 0xEC, 0xA4};//esp32 самоделка
uint8_t broadcastAddress3[] = {0x30, 0x83, 0x98, 0x88, 0xE7, 0xBD};
uint8_t broadcastAddress4[] = {0x78, 0x21, 0x84, 0xC6, 0xA8, 0xA4};//78:21:84:C6:A8:A4 esp32 L105
typedef struct struct_message {
    int id;
    float temp;
    float hum;
    int readingId;
    int bat;
} struct_message;
struct_message myData;
unsigned long previousMillis = 0;   // Stores last time temperature was published
const long interval = 10000;        // Interval at which to publish sensor readings
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
unsigned int readingId = 0;

// Insert your SSID
constexpr char WIFI_SSID[] = "VOVA-47";
 esp_now_peer_info_t peerInfo;
//*****************************************************************************
String  Time_str = "--:--:--";
String  Date_str = "-- --- ----";
int     wifi_signal, CurrentHour = 0, CurrentMin = 0, CurrentSec = 0, EventCnt = 0, vref = 1100;
//################ PROGRAM VARIABLES and OBJECTS ##########################################
#define max_readings1 24 // Limited to 3-days here, but could go to 5-days = 40  
#define max_readings 7 // Limited to 7-days h

Forecast_record_type  WxConditions[1];
Forecast_record_type  WxForecast[max_readings1]; 

float pressure_readings[max_readings1]    = {0};
float temperature_readings[max_readings1] = {0};
float humidity_readings[max_readings1]    = {0};
float rain_readings[max_readings1]        = {0};
float snow_readings[max_readings1]        = {0};

//Day of the week
//const char* weekday_D[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
int mon = 1; //Month
int date = 1;
int dow = 6;
int years = 2022;
float voltage ;
int volt = 0;
int temp;
//int tempmax;
//int tempmin;
int hum;
RTC_DATA_ATTR int tempmax = 100;//несбрасываемые в режиме сна переменная
RTC_DATA_ATTR int tempmin = 270;
boolean zntemp = 1;//1+,0-
RTC_DATA_ATTR boolean znmin = 1;
RTC_DATA_ATTR boolean znmax = 0;
RTC_DATA_ATTR int tik = 0;//такты по 20мин до полного обновления
RTC_DATA_ATTR int tMin = 0;//минуты
RTC_DATA_ATTR int tHour = 0;//часы
RTC_DATA_ATTR int tax = 0;//время макс темп
RTC_DATA_ATTR int tin = 0;//время мин темп
RTC_DATA_ATTR int tdata = 0;//время мин темп
bool forcast ;
int but=0;
bool ht=0;
bool kalen=0;
int sen =0;
boolean ntp=0;//флаг соед с нтп
//const char* month_M[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
long SleepDuration   = 20; // сон в минутах Sleep time in minutes, aligned to the nearest minute boundary, so if 30 will always update at 00 or 30 past the hour
int  WakeupHour      = 8;  // Don't wakeup until after 07:00 to save battery power
int  SleepHour       = 23; // Sleep after 23:00 to save battery power
long StartTime       = 0;
long SleepTimer      = 0;
long Delta           = 10; // ESP32 rtc speed compensation, prevents display at xx:59:yy and then xx:00:yy (one minute later) to save power


#if defined(_HAS_SDCARD_) && !defined(_USE_SHARED_SPI_BUS_)
SPIClass SDSPI(VSPI);
#endif


#define _HAS_COLOR_






bool setupSDCard(void)
{
#if defined(_HAS_SDCARD_) && !defined(_USE_SHARED_SPI_BUS_)
    SDSPI.begin(SDCARD_SCLK, SDCARD_MISO, SDCARD_MOSI);
    return SD.begin(SDCARD_CS, SDSPI);
#elif defined(_HAS_SDCARD_)
    return SD.begin(SDCARD_CS);
#endif
    return false;
}






void setup()
{
    bool rlst = false;
    Serial.begin(115200);
      StartTime = millis();
    Serial.println("setup");
print_GPIO_wake_up();
pinMode(37, INPUT); 
pinMode(38, INPUT);
pinMode(39, INPUT);

   SPI.begin(EPD_SCLK, EPD_MISO, EPD_MOSI);

    display.init();
    rlst = setupSDCard();

  

timeClient.setTimeOffset(10800);  

//display.setRotation(0);
 //  display.setCursor(20, display.height() - 15);

 //  String sizeString = "SD:" + String(SD.cardSize() / 1024.0 / 1024.0 / 1024.0) + "G";
 //  display.println(rlst ? sizeString : "SD:N/A");

/*  int16_t x1, x2;
   uint16_t w, h;
    String str = GxEPD_BitmapExamplesQ;
    str = str.substring(2, str.lastIndexOf("/"));
    display.getTextBounds(str, 0, 0, &x1, &x2, &w, &h);
   display.setCursor(display.width() - w - 5, display.height() - 15);
    display.println(str);
   
 

   display.update();
Serial.println(sizeString);
*/ 
htu.begin();
delay (100);
  if (!htu.begin()) {
    
    Serial.println("Couldn't find sensor!");
   ht=1;
   // BeginSleep();
    //while (1);
  }

}





void loop()
{
//PageWeather1();
// BeginSleep();
 
  if(StartWiFi())
    {
     ntpTime();
     if(ntp==0)notTime();
     Serial.print("tik=");
       Serial.println(tik) ; //время без интернета
      if(but==38)readWeather(); 
      if(but==37)
      {forcast=1;//forcast=0-погода на 7 дней через 24 ч  forcast= 1- на 3 дня через 3ч
        readWeather(); 
      } 
      if(tdata==0)now1=1;
      
      Serial.print("tdata=");
       Serial.println(tdata) ; //счет пропуска при передачи данных через NOW  считеам до 3 передаем при 0
         tdata++; 
      if(tdata>2)tdata=0;
     StopWiFi();
     
    }
    else
    {tdata=0;
      notTime();
      
    }


  if((tHour==0)&&(tMin<20))
 {
  tempmax = 100;//обнуление суточных данных
 tempmin = 270;
 znmin = 1;//+
 znmax = 0;//-
 }   
  if((tHour>5)&&(tHour<22))
   {
     testSpeaker();   
   }
   


  htu21();  
if(but==37)Kalendar();
//if(but==38)PageWeather1();
if(but==38)GxepdPage3();
if(but==39)GxepdPage2();
if(but==0)
{GxepdPage2();
if(now1==1)Now();// передача данных между несколькими esp32 esp8266 в одной WiFi сети
}
//Kalendar();
/*if(kalen==1)
{
  if(StartWiFi())
    {
      forcast=1;//forcast=0-погода на 7 дней через 24 ч  forcast= 1- на 3 дня через 3ч
        readWeather();
        StopWiFi();
        Kalendar();
    }
}
*/

    display.powerDown();
 Serial.println("sleep");
 BeginSleep();
}
/*
void showFont(const char name[], const GFXfont *f)
{
    display.fillScreen(GxEPD_WHITE);
    display.setTextColor(GxEPD_BLACK);
     display.setTextColor(GxEPD_RED);
    display.setFont(f);
    display.setCursor(0, 0);
    display.println();
    display.println(name);
    display.println(" !\"#$%&'()*+,-./");
    display.println("0123456789:;<=>?");
    display.println("@ABCDEFGHIJKLMNO");
    display.println("PQRSTUVWXYZ[\\]^_");
    display.println("`abcdefghijklmno");
    display.println("pqrstuvwxyz{|}~ ");
    display.update();
    delay(3000);
}

void drawCornerTest()
{
    display.drawCornerTest();
    delay(5000);
    uint8_t rotation = display.getRotation();
    for (uint16_t r = 0; r < 4; r++) {
        display.setRotation(r);
        display.fillScreen(GxEPD_WHITE);
        display.fillRect(0, 0, 8, 8, GxEPD_BLACK);
        display.fillRect(display.width() - 18, 0, 16, 16, GxEPD_BLACK);
        display.fillRect(display.width() - 25, display.height() - 25, 24, 24, GxEPD_BLACK);
        display.fillRect(0, display.height() - 33, 32, 32, GxEPD_BLACK);
        display.update();
        delay(5000);
    }
    display.setRotation(rotation); // restore
}*/
