#include <microDS3231.h>
MicroDS3231 rtc;
#include <GyverButton.h>
#include <GyverOLED.h>
GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
// можно передать адрес: GyverOLED oled(0x3C);
#define klapan1 D8  //пин клапана 1
#define klapan2 D7  //пин клапана 2
GButton butt1(D5); //кнопка управления клапаном 1
GButton butt2(D6); //кнопка управления клапаном 2
bool kl_mode1 = 0; //состояние клапана 1
bool kl_mode2 = 0; //состояние клапана 2
uint32_t delayTime; //переменная для интервала опроса RTC и коммутации клапанов
#define rtc_interval 1  //интервала опроса RTC и коммутации клапанов (мин)
uint32_t delayDisp; //переменная для показа даты-времени на несколько сек
#define disp_int 5  //интервал показа даты - времени (сек)
bool dispTime_fl = 0; //флаг отображения даты-времени
#define open_int 30  //интервал закрытия клапанов, если открыты вручную и не настало время открытия (их работы)(мин)
uint32_t close_tmr;  //переменная для таймера закрытия клапанов после их открытия вручную
const uint8_t closed_60x60[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xE0, 0xF0, 0xF0, 0x78, 0x78, 0x3C, 0x3C, 0x1C, 0x1E, 0x1E, 0x1E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x3C, 0x3C, 0x3C, 0x78, 0x78, 0xF0, 0xF0, 0xE0, 0xC0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xFC, 0x7E, 0x3F, 0x0F, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0xFE, 0xFC, 0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xE0, 0xFC, 0xFF, 0xFF, 0x1F, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x83, 0x0F, 0x0F, 0x1C, 0x1C, 0x1E, 0x0E, 0x0E, 0xFE, 0xFE, 0xFE, 0xC0, 0xC0, 0xFE, 0xFE, 0xFE, 0x0E, 0x0E, 0x1E, 0x1C, 0x9C, 0x8F, 0xCF, 0xC3, 0xE0, 0xE0, 0xF0, 0xF8, 0x78, 0x7C, 0x3C, 0x1E, 0x1F, 0x0F, 0x0F, 0x07, 0x07, 0x1F, 0xFF, 0xFF, 0xFC, 0xE0, 0x00,
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x07, 0x07, 0x07, 0x07, 0x07, 0x87, 0xC7, 0xC3, 0xE1, 0xE1, 0xF1, 0xF9, 0x7B, 0x7F, 0x3F, 0x3F, 0x1F, 0x0F, 0x0F, 0x07, 0x07, 0x0F, 0x0F, 0x1F, 0x1C, 0x3C, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
  0x0F, 0x7F, 0xFF, 0xFF, 0xF0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0x7F, 0x7F, 0x3E, 0x3E, 0x1E, 0x0F, 0x0F, 0x0F, 0x1F, 0x3F, 0x3B, 0x39, 0x38, 0x38, 0x3C, 0x1E, 0x1E, 0x0E, 0x0E, 0x0E, 0xFE, 0xFC, 0xF8, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE1, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF0, 0xFF, 0xFF, 0x7F, 0x0F,
  0x00, 0x00, 0x03, 0x0F, 0x3F, 0x7F, 0xFE, 0xFE, 0xFF, 0x8F, 0x07, 0x07, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x7C, 0xFF, 0xC7, 0xC7, 0xFF, 0x7C, 0x38, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xFC, 0x7F, 0x3F, 0x0F, 0x03, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0F, 0x1F, 0x1E, 0x3C, 0x78, 0xF8, 0xF0, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xE1, 0xE1, 0xF0, 0xF8, 0x7C, 0x3C, 0x1E, 0x1F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const uint8_t opened_60x60[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFC, 0xFE, 0xFE, 0x1F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1F, 0xFE, 0xFE, 0xFC, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0F, 0x1F, 0x1E, 0x3C, 0x3C, 0x3C, 0x3C, 0x1E, 0x1E, 0x1F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x3C, 0x3C, 0x3C, 0x3C, 0x1E, 0x1F, 0x0F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xFE, 0xFE, 0xFE, 0x1E, 0x1E, 0x1E, 0x3C, 0xFC, 0xFC, 0xF8, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8, 0x7F, 0x3F, 0x3F, 0x3F, 0x1E, 0x1E, 0x1E, 0x3F, 0x3F, 0x3F, 0x7F, 0xF8, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x0F, 0x1F, 0x7E, 0xFC, 0xF8, 0xF0, 0xC0, 0x00,
  0xFF, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0xF8, 0xF0, 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0x78, 0x78, 0x78, 0x78, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
  0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3C, 0x3C, 0x3C, 0xBC, 0xFC, 0xFC, 0xFC, 0xBC, 0x3C, 0x3C, 0x3C, 0x3F, 0x3F, 0x3F,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0xFE, 0xFF, 0x1F, 0x0F, 0x1F, 0xFF, 0xFE, 0xF8, 0xE0, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x0F, 0x0F, 0x0E, 0x0F, 0x0F, 0x0F, 0x07, 0x01, 0x00, 0x00, 0x00,
};
void setup() {
  //Serial.begin(9600);
  butt1.setDebounce(180);        // настройка антидребезга (по умолчанию 80 мс)
  butt2.setDebounce(180);        // настройка антидребезга (по умолчанию 80 мс)
  // butt1.setTimeout(300);        // настройка таймаута на удержание (по умолчанию 500 мс)
  // butt2.setTimeout(300);        // настройка таймаута на удержание (по умолчанию 500 мс)
  butt1.setType(LOW_PULL);
  butt2.setType(LOW_PULL);
  //butt1.setDirection(NORM_OPEN);
  butt1.setTickMode(AUTO);  //авто режим опроса кнопок
  butt2.setTickMode(AUTO);
  oled.init();
  oled.clear();
  oled.drawBitmap(2, 2, closed_60x60, 60, 60);
  oled.drawBitmap(66, 2, closed_60x60, 60, 60);
  oled.update();
  pinMode (klapan1, OUTPUT);
  pinMode (klapan2, OUTPUT);
  digitalWrite(klapan1, kl_mode1);
  digitalWrite(klapan2, kl_mode2);
  // проверка наличия модуля на линии i2c
  /* if (!rtc.begin()) {
     Serial.println("DS3231 not found");
     for (;;);
    }*/
  // получаем все данные в структуру
  DateTime now = rtc.getTime();
}
void loop() {
  if (millis() - delayTime > rtc_interval * 60 * 1000) { //интервал опроса RTC и коммутации клапанов
    delayTime = millis();
    DateTime now = rtc.getTime();
  }
  if ((now.day == 1 || now.day == 2 || now.day == 3 || now.day == 4 || now.day == 5 || now.day == 6) && (!kl_mode1 || !kl_mode2)) {           //откроем оба клапана по времени в будни и субботу
    if (now.hour == 8  && now.minute == 0) openAll();
  }
  if (kl_mode1 || kl_mode2 && millis() - close_tmr > open_int * 60 * 1000) {           // закроем оба клапана по времени каждый день, а в субботу по-раньше, или если сработал таймер после ручного включения
    if (now.hour == 18  && now.minute == 0) closeAll();                               // если вручную закрыть-открыть до времени закрытия, то закроются не ранее чем сработает таймер
    else if (now.day == 6 && now.hour == 15  && now.minute == 0) closeAll();
  }
  buttTick();
  if (dispTime_fl)  drawData();
}