#ifndef __SAMOVAR_H_
#define __SAMOVAR_H_

#ifndef ESP32
#error This code is designed to run on ESP32 platform, not Arduino, not ESP8266! Please check your Tools->Board setting.
#endif

#define SAMOVAR_VERSION F("dm_1.3.1 (6.25)")

//#define __SAMOVAR_DEBUG

#include <OneWire.h>
#include <DallasTemperature.h>
#include <ESPAsyncWebServer.h>
#include <PID_v1.h>
#include <PID_AutoTune_v0.h>
#include <GyverButton.h>
#include <ESPmDNS.h>
#include <ESP32PWM.h>
#include "simple_queue.h"

//определение поддерживаемых плат
#define DEVKIT 1
#define ESP32S3 3


#define BitIsSet(reg, bit) ((reg & (1<<bit)) != 0)

//#define USE_WEB_SERIAL                      //использовать библиотеку WebSerial для отладки

#define WRITE_PROGNUM_IN_LOG                 // писать в лог номер текущей строки программы

#include "INI.h"
// Автоматическое определение типа платы
#if defined(ARDUINO_ESP32S3_DEV)
#undef BOARD
#define BOARD ESP32S3
#elif defined(ARDUINO_ESP32_DEV)
#undef BOARD
#define BOARD DEVKIT
#endif

// Если плата не определена автоматически, используем ESP32S3 по умолчанию
#if not defined(BOARD)
#define BOARD ESP32S3
#endif

//**************************************************************************************************************
// Распиновка ESP32S3
  //**************************************************************************************************************
  #if BOARD == ESP32S3
  //#pragma message ("ESP32S3") 
  // поставил пины которые нельзя использовать при загрузке


  #define STEPPER_STEP 16
  #define STEPPER_DIR 0 // загрузочный
  #define STEPPER_EN 15

  #define STEPPER2_STEP 7
  #define STEPPER2_DIR 3 // загрузочный
  #define STEPPER2_EN 6

  #define RELE_CHANNEL1 2             //используется для пускателя, который включает нагреватель
  #define RELE_CHANNEL2 42             //в режиме "Пиво" используется для включения мешалки
  #define RELE_CHANNEL3 41             //используется для клапана, открывающего/закрывающего воду охлаждения
  #define RELE_CHANNEL4 40             //если не используется регулятор с управлением, выход используется для управления разгоном

  #define ONE_WIRE_BUS 12

  #define SERVO_PIN 10

  #define BTN_PIN 47

  #define LUA_PIN 4
  #define LUA_PIN2 5
  #define LUA_PIN3 1
  #define CULL_PIN 20

  #define ALARM_BTN_PIN 48

  #define WATERSENSOR_PIN 13

  #define WHEAD_LEVEL_SENSOR_PIN 19

  #define LCD_SDA 8
  #define LCD_SCL 9

  #define RXD2 18
  #define TXD2 17

  #define WATER_PUMP_PIN 11

  #define BZZ_PIN 39
  #define BARDA_LEVEL_UP 21 //Пины регулятора уровня барды
  #define BARDA_LEVEL_DWN 14 // Светодиод 

// Распиновка ESP32_DEVKIT V1

  #elif BOARD == DEVKIT
  // Пины для шагового двигателя
  #define STEPPER_STEP 26
  #define STEPPER_DIR 32
  #define STEPPER_EN 33
  #define STEPPER2_STEP 19
  #define STEPPER2_DIR 18 
  #define STEPPER2_EN 23
  //**************************************************************************************************************
  // Пины для релейного модуля
  #define RELE_CHANNEL1 2             //используется для пускателя, который включает нагреватель
  #define RELE_CHANNEL2 15 //было 34  //в режиме "Пиво" используется для включения мешалки
  #define RELE_CHANNEL3 14            //используется для клапана, открывающего/закрывающего воду охлаждения
  #define RELE_CHANNEL4 13            //если не используется регулятор с управлением, выход используется для управления разгоном
  //**************************************************************************************************************
  // Пин для DS1820
  #define ONE_WIRE_BUS 5
  //**************************************************************************************************************
  // Пины для сервопривода
  #define SERVO_PIN 25
  //**************************************************************************************************************
  // Пин кнопки - не обязательно, но удобно
  #define BTN_PIN 39
  //**************************************************************************************************************
  // Пин для использования в Lua-скриптах
  #define LUA_PIN 34
  //**************************************************************************************************************
  // Пин аварийной кнопки
  #define ALARM_BTN_PIN 35
  //**************************************************************************************************************
  // Пины сенсора охлаждения воды - используется для отключения нагрева в случае отсутствия охлаждения. Не обязательно, но безопасно
  #define WATERSENSOR_PIN 36
  //**************************************************************************************************************
  // Пины сенсора уровня флегмы в узле отбора - используется для уменьшения нагрева при начале захлебывания колонны. Не обязательно, но безопасно
  #define WHEAD_LEVEL_SENSOR_PIN 27
  //**************************************************************************************************************
  // Шина I2C
  #define LCD_SDA 21
  #define LCD_SCL 22
  //**************************************************************************************************************
  // Пины UART2 для взаимодействия с регулятором напряжения
  #define RXD2 16
  #define TXD2 17
  //**************************************************************************************************************
  // Пин для управления насосом по ШИМ
  #define WATER_PUMP_PIN 4
  //**************************************************************************************************************
  // Пин для управления вентилятором по ШИМ
  #define CULL_PIN 4  
  //**************************************************************************************************************
  // Пин для Buzzer
  #define BZZ_PIN 12
  //**************************************************************************************************************
  #else
  #pragma message ("PLATFORM NOT DEFINED")
  #error
  #endif

#define STEPPER_STEPS 400 //количество шагов, 200 x MS
#define STEPPER_STEP_ML 1020 //количество шагов на 1 мл жидкости для драйвера с шагами 1/2
#define STEPPER_MAX_SPEED 8000

#define WHLS_ALARM_TIME 3 //Секунд, через сколько сработает тревога по уровню флегмы

#define WF_ALARM_COUNT 20 //Секунд до отключения нагрева, если в течении этого времени не будет подана вода охлаждения

//Максимальный угол сервопривода
#define SERVO_ANGLE 180
// Количество емкостей. (0 используется всегда). Для расчета позиции серво считаем угол поворота между емкостями
// равным 180 / CAPACITY_NUM
#define CAPACITY_NUM 10
#define MAX_PRG 29 //Максимум строк в программе 0-29

//**************************************************************************************************************
  #ifdef USE_DISPLAY
  #include <ASOLED_ESP8266.h>     
  #endif
  #ifdef USE_DISP_LC
  #include <LiquidCrystal_I2C.h>   
  #endif

#ifdef USE_PRESSURE_1WIRE
#undef USE_PRESSURE_XGZ
#endif

#ifndef SAM_NO_BEER_PRG
#define SAM_BEER_PRG
#endif

#ifdef USE_WEB_SERIAL
#include <WebSerial.h>
#endif

SemaphoreHandle_t xSemaphore = NULL;
SemaphoreHandle_t xMsgSemaphore = NULL;
StaticSemaphore_t xMsgSemaphoreBuffer;

SemaphoreHandle_t xI2CSemaphore = NULL;
StaticSemaphore_t xI2CSemaphoreBuffer;

SemaphoreHandle_t xSemaphoreAVR = NULL;
StaticSemaphore_t xSemaphoreBufferAVR;

SemaphoreHandle_t xSemaphoreSerial = NULL;
StaticSemaphore_t xSemaphoreBufferSerial;

SemaphoreHandle_t msgMutex = NULL; //Семафор для сообщений в web интерфейсе

#ifdef __cplusplus
extern "C" {
#endif

uint8_t temprature_sens_read();

#ifdef __cplusplus
}
#endif

uint8_t temprature_sens_read();

//#define __SAMOVAR_NOT_USE_WDT

//**************************************************************************************************************
// Режимы работы регулятора напряжения
#define POWER_WORK_MODE F("0")
#define POWER_SPEED_MODE F("1")
#define POWER_SLEEP_MODE F("2")
#define POWER_ERROR_MODE F("3")
//**************************************************************************************************************
// Модели регуляторов напряжения
#define NO_POVER_REG 0
#define KVIC 1
#define KVIC9600 2
#define RMVK 3
#define STAB_AVR 4
#define UNI_PROTOCOL 5
#define MODBUS_RTU 6
#define PWM 7


#define RMVK_DEFAULT_READ_TIMEOUT 1100 // Таймаут по умолчанию (мс)
#define RMVK_READ_DELAY 300 // Задержка между запросами (мс)


#ifndef LUA_BEER
#define LUA_BEER ""
#endif

#ifndef LUA_DIST
#define LUA_DIST ""
#endif

#ifndef LUA_BK
#define LUA_BK ""
#endif

#ifndef LUA_NBK
#define LUA_NBK ""
#endif

#ifndef LUA_RECT
#define LUA_RECT ""
#endif

#define USE_LittleFS

#ifdef USE_LittleFS
//#pragma message ("USE LITTLEFS")
#ifdef ESP_ARDUINO_VERSION
#include <LittleFS.h>
#define SPIFFS LittleFS
#else
#include <LITTLEFS.h>
#define SPIFFS LITTLEFS
#endif
#else
#pragma message ("USE SPIFFS")
#include <SPIFFS.h>
#endif

#include <FS.h>

#include <AsyncMqttClient.h>
#define PAYLOADSIZE 800
AsyncMqttClient mqttClient;

void WriteConsoleLog(String StringLogMsg);

//**************************************************************************************************************
// Описание переменных
//**************************************************************************************************************

//**************************************************************************************************************
// Переменные для меню
  #ifdef USE_DISP_LC
  LiquidCrystal_I2C LQ(0x27, 20, 4);
  #endif
uint8_t multiplier = 1;

char ipst[16] = "000.000.000.000";
//char* ipstr = (char*)ipst;
char startval_text_val[20];
//char* startval_text = (char*)startval_text_val;
char* power_text_ptr = (char*)"ON";
char* calibrate_text_ptr = (char*)"Start";
char* pause_text_ptr = (char*)"Pause";
String StrCrt;
String Crt;
//uint8_t CurMin, OldMin;
//**************************************************************************************************************

/** Task handle for the  value read task */
TaskHandle_t SysTickerButton = NULL;
TaskHandle_t SysTickerTask1 = NULL;
TaskHandle_t GetClockTask1 = NULL;
TaskHandle_t BuzzerTask = NULL;
TaskHandle_t GetBMPTask = NULL;
volatile bool BuzzerTaskFl;
TaskHandle_t PowerStatusTask = NULL;

AsyncWebServer server(80);

AsyncWebSocket ws("/ws");
AsyncEventSource events("/events");

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress DSAddr[6];

#ifdef USE_STEPPER_ACCELERATION
#define GS_FAST_PROFILE 10
#else
#define GS_NO_ACCEL
#endif

#include <GyverStepper2.h>
#include <DNSServer.h>

GStepper2< STEPPER2WIRE> stepper(STEPPER_STEPS, STEPPER_STEP, STEPPER_DIR, STEPPER_EN);
GStepper2< STEPPER2WIRE> stepper2(STEPPER_STEPS, STEPPER2_STEP, STEPPER2_DIR, STEPPER2_EN);

File fileToAppend;

GButton btn(BTN_PIN);
GButton alarm_btn(ALARM_BTN_PIN);


double Input, Output, Setpoint;
double Kp, Ki, Kd;

//Relay relay(RELAY_PIN, RELAY_PERIOD);
PID heaterPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
int periodInSeconds = 6;

uint8_t ATuneModeRemember = 2;
double aTuneStep = 50;
double aTuneNoise = 1;
unsigned int aTuneLookBack = 9;
boolean tuning = false;

PID_ATune aTune(&Input, &Output);

GButton whls(WHEAD_LEVEL_SENSOR_PIN);
#if BOARD == ESP32S3
GButton BLU_s(BARDA_LEVEL_UP);
GButton BLD_s(BARDA_LEVEL_DWN);
#endif

static ESP32PWM servo_pwm;
static ESP32PWM Power_PWM;
static ESP32PWM Culler_PWM;

//GButton nbkls(LUA_PIN); //не используется


#ifdef USE_WEB_SERIAL
//WebSerialClass WebSerial;
#endif
  String StIP;//храним IP
  
DNSServer dns;

String jsonstr2;

enum SamovarCommands {SAMOVAR_NONE, SAMOVAR_START, SAMOVAR_POWER, SAMOVAR_RESET, CALIBRATE_START, CALIBRATE_STOP, SAMOVAR_PAUSE, SAMOVAR_CONTINUE, SAMOVAR_SETBODYTEMP, SAMOVAR_DISTILLATION, SAMOVAR_BEER, SAMOVAR_BEER_NEXT, SAMOVAR_BK, RUN_NBK, SAMOVAR_SELF_TEST, SAMOVAR_DIST_NEXT, SAMOVAR_NBK_NEXT};
volatile SamovarCommands sam_command_sync;                    // переменная для передачи команд между процессами

enum SAMOVAR_MODE {SAMOVAR_RECTIFICATION_MODE, SAMOVAR_DISTILLATION_MODE, SAMOVAR_BEER_MODE, SAMOVAR_BK_MODE, SAMOVAR_NBK_MODE, SAMOVAR_SUVID_MODE, SAMOVAR_LUA_MODE, SAMOVAR_MQTT_MODE};
volatile SAMOVAR_MODE Samovar_Mode;
volatile SAMOVAR_MODE Samovar_CR_Mode;

enum MESSAGE_TYPE {ALARM_MSG = 0, WARNING_MSG = 1, NOTIFY_MSG = 2, NONE_MSG = 100};
volatile MESSAGE_TYPE msg_type;

enum get_web_type {GET_CONTENT, SAVE_FILE_OVERRIDE, SAVE_FILE_IF_NOT_EXIST};

struct SetupEEPROM {
    uint8_t flag;                                               // Флаг для инициализации EEPROM
    uint8_t Mode;                                               // Режим работы Самовара
    float DistTemp;                                             // Температура завершения дистилляции
    uint8_t DistTimeF;                                          // Время контроля завершения дистилляции (мин)
    bool UsePreccureCorrect;                                    // Коррекция температуры отбора тела по давлению
    bool useautospeed;                                          // Автокорректировка скорости
    uint8_t autospeed;                                          // Процент изменения скорости
    bool useautopowerdown;                                      // Автокорректировка мощности
    float MaxPressureValue;                                     // Максимальное давление для аварийного режима
    bool UseBuzzer;                                             // Использовать пищалку
    bool UseBBuzzer;                                            // Пищалка в браузере
    bool ChangeProgramBuzzer;                                   // Пищалка при смене программы
    char SteamColor[20];                                        // Цвет температуры пара
    uint8_t SteamAdress[8];                                     // Адрес датчика пара
    float DeltaSteamTemp;                                       // Корректировка датчика пара
    float SetSteamTemp;                                         // Уставка температуры пара
    uint16_t SteamDelay;                                        // Задержка паузы насоса пара (сек)
    char PipeColor[20];                                         // Цвет температуры царги
    uint8_t PipeAdress[8];                                      // Адрес датчика царги
    float DeltaPipeTemp;                                        // Корректировка датчика царги
    float SetPipeTemp;                                          // Уставка температуры царги
    uint16_t PipeDelay;                                         // Задержка паузы насоса царги (сек)
    char WaterColor[20];                                        // Цвет температуры воды
    uint8_t WaterAdress[8];                                     // Адрес датчика воды
    float DeltaWaterTemp;                                       // Корректировка датчика воды
    float SetWaterTemp;                                         // Уставка температуры воды
    uint16_t WaterDelay;                                        // Задержка паузы насоса воды (сек)
    char TankColor[20];                                         // Цвет температуры куба
    uint8_t TankAdress[8];                                      // Адрес датчика куба
    float DeltaTankTemp;                                        // Корректировка датчика куба
    float SetTankTemp;                                          // Уставка температуры куба
    uint16_t TankDelay;                                         // Задержка паузы насоса куба (сек)
    char ACPColor[20];                                          // Цвет температуры ТСА
    uint8_t ACPAdress[8];                                       // Адрес датчика ТСА
    float DeltaACPTemp;                                         // Корректировка датчика ТСА
    float SetACPTemp;                                           // Уставка температуры ТСА
    uint16_t ACPDelay;                                          // Задержка включения насоса ТСА (сек)
    bool UseDS;                                                 // Использовать DS18B20
    bool UseNTC;                                                // Использовать термисторы
    float NTC_dT[5];                                            // Поправки для термисторов
    uint16_t m_adc[151];                                        // Характеристика термисторов
    uint16_t StepperStepMl;                                     // Шагов на мл для шагового двигателя
    uint16_t NBK_StepperStepMl;                                 // Шагов на мл для НБК
    bool StRev1;                                                // Реверс шагового двигателя 1
    bool UsePump2;                                              // Использование 2-го насоса над ЦП
    float SpPump2;                                              // Скорость отбора голов над ЦП
    bool StRev2;                                                // Реверс шагового двигателя 2
    bool UseWP;                                                 // Управление водяным насосом
    float Trg_W_T;                                              // Целевая температура воды
    float Alrm_Wt_T;                                            // Температура оповещения о воде
    float Max_Wt_T;                                             // Макс. температура воды
    float Max_St_T;                                             // Макс. температура пара
    float Max_ACP_T;                                            // Макс. температура ТСА
    float Ch_Pwr_Md_St_T;                                       // Температура перехода в рабочий режим
    float Opn_Vlv_Tnk_T;                                        // Температура открытия клапана воды
    float D_Cls_Vlv;                                            // Разность температур закрытия клапана
    uint8_t PWM_L_V;                                            // Нижний уровень PWM (%)
    uint8_t PWM_St_V;                                           // Стартовый уровень PWM (%)
    uint8_t UseWV;                                              // Управление водяным клапаном
    int8_t servoDelta[11];                                      // Коррекция углов сервопривода
    uint8_t PwrType;                                            // Тип регулятора мощности
    bool CheckPower;                                            // Контроль регулятора напряжения
    float HeaterResistant;                                      // Сопротивление ТЭНа
    uint16_t PwStartPause;                                      // Задержка перед разгоном (мс)
    bool rele1;                                                 // Состояние реле 1
    bool rele2;                                                 // Состояние реле 2
    bool rele3;                                                 // Состояние реле 3
    bool rele4;                                                 // Состояние реле 4
    bool PWM_Cull;                                              // Включение кулера
    uint16_t Cull_N_Min;                                        // Мин. обороты кулера (%)
    uint16_t Cull_N_Max;                                        // Макс. обороты кулера (%)
    float Cull_T_ON;                                            // Температура включения кулера
    float Cull_T_Max;                                           // Температура макс. оборотов
    float Kp;                                                   // Коэффициент P PID-регулятора
    float Ki;                                                   // Коэффициент I PID-регулятора
    float Kd;                                                   // Коэффициент D PID-регулятора
    float StbVoltage;                                           // Напряжение в режиме поддержания
    float BVolt;                                                // Напряжение в режиме кипения
    bool UseST;                                                 // Использовать разгонный тэн
    float Boilng_T;                                             // Температура кипения (пиво)
    float Heat_Dt;                                              // Разница температур для разгона
    float Axlr_Heat_Dt;                                         // Разница для включения разгонного ТЭНа
    float Nbk_Tn;                                               // Опорная температура барды
    float NbkIn;                                                // Инерция
    float NBK_Mult_Pause;                                       // Пауза после захлёба (инерций)
    float NbkDelta;                                             // Дельта T барды
    float NbkDM;                                                // Шаг мощности
    float NbkDP;                                                // Шаг подачи
    float NBK_Pump_Limit;                                       // Макс. производительность насоса (л/ч)
    float NbkSteamT;                                            // Предел Т пара
    float NbkOwPress;                                           // Давление захлёба
    bool Use_NBK_Delta_Pressure;                                // Коррекция температуры по давлению
    float NBK_WPrc;                                             // Процент использования оптимизации
    char SavedSSID[12];                                         // SSID WiFi
    char SavedPASS[12];                                         // Пароль WiFi
    bool UseBlynk;                                              // Использование Blynk
    char BlynkUrl[30];                                          // URL сервера Blynk
    char blynkauth[33];                                         // Blynk авторизация
    bool UseTg;                                                 // Уведомления в Telegram
    char tg_token[50];                                          // Telegram токен
    char tg_chat_id[14];                                        // Telegram chat ID
    char videourl[120];                                         // URL видеопотока
    bool UseMQTT;                                               // Использование MQTT
    char MQTT_Serv[50];                                         // MQTT сервер
    bool Use_BMP180;                                            // Использование BMP180
    bool UseHLS;                                                // Использовать датчик флегмы
    bool UseHLS_D;                                              // Переключение на след программу при срабатывании датчика уровня
    bool DUFnpn;                                                // Тип датчика N-P-N
    uint8_t UseWS;                                              // Использование датчика протока
    uint16_t Ws_Calbr;                                          // Калибровка датчика потока
    bool UseBTN;                                                // Использование кнопки
    bool UseA_BTN;                                              // Использование аварийной кнопки
    uint8_t TimeZone;                                           // Часовой пояс
    uint8_t LogPeriod;                                          // Период записи логов
    bool UseBdT_Aset;                                           // Автокоррекция температуры тела
    bool dbg;                                                   // Отладочные сообщения
    char MQTT_User[16];                                         // MQTT пользователь
    char MQTT_Pass[16];                                         // MQTT пароль
    uint16_t MQTT_Port;                                         // MQTT порт
};
struct DSSensor {
  DeviceAddress Sensor;                                        //адрес датчика температуры
  float avgTemp;                                               //средняя температура с датчика
  float SetTemp;                                               //уставка по температуре, при достижении которой требуется реакция
  float BodyTemp;                                              //температура, с которой начался отбор тела
  uint16_t Delay;                                              //Время задержки включения насоса в секундах при выходе температуры за значение уставки
  float PrevTemp;                                              //Предыдущая температура
  float Start_Pressure;                                        //Стартовое давление при начале отбора
  int ErrCount;                                                //Счетчик ошибок для оповещения о не возможности провести чтение с датчика
  float LogPrevTemp;                                           //Хранение предыдущей температуры для записи лога
  float StartProgTemp;                                         //Хранение температуры, которая была на начало строки программы
};

struct WProgram {
  String WType;                                                //тип отбора - головы или тело
  uint16_t Volume;                                             //объем отбора в мл
  float Speed;                                                 //скорость отбора в л/ч
  uint8_t capacity_num;                                        //номер емкости для отбора
  float Temp;                                                  //температура, при которой отбирается эта часть погона. 0 - определяется автоматически
  uint16_t Power;                                              //напряжение, при которой отбирается эта часть погона.
  uint8_t TempSensor;                                          //температурный сенсор, используемый в программе Пиво для контроля нагрева
  float Time;                                                  //время, необходимое для отбора программы
};

SetupEEPROM SamSetup;

DSSensor SteamSensor;                                          //сенсор температуры пара вверху колонны
DSSensor PipeSensor;                                           //сенсор температуры в царге на 2/3 высоты
DSSensor WaterSensor;                                          //сенсор температуры охлаждающей воды или флегмы
DSSensor TankSensor;                                           //сенсор температуры в кубе
DSSensor ACPSensor;                                            //сенсор температуры в ТСА

WProgram program[30];                                          //массив строк для записи программы отбора.

//**************************************************************************************************************
const char* host = SAMOVAR_HOST;

//**************************************************************************************************************
uint8_t DScnt = 0;
uint8_t STcnt = 0;                                              // Счетчик для записи текущего статуса
//uint8_t tcnt = 0;
bool bmefound = true;
volatile bool PowerOn = false;                                  // Индикатор включенного питания
volatile bool PauseOn = false;                                  // Индикатор постановки отбора на паузу
volatile bool StepperMoving = false;                            // Индикатор движущегося шагового двигателя
volatile bool Stepper2Moving = false;                            // Индикатор движущегося 2 шагового двигателя
volatile bool program_Pause;                                    // Признак, что запущена программа паузы
volatile bool program_Wait;                                     // Признак, что программа ожидает возврата колонны в заданные параметры
volatile bool heater_state;                                     // Статус нагрева при затирке
volatile bool loop_lua_fl = false;                              // Запускать lua скрипт в цикле
volatile bool show_lua_script = false;                          // Показывать выполняемый lua скрипт в логе и в Serial
volatile bool is_self_test;                                     // Находимся в режиме самотестирования
volatile bool SetScriptOff;                                     // Признак остановки Lua скрипта
bool boil_started;                                              // Флаг, определяющий, что кипение началось
bool valve_status;                                              // Состояние клапана подачи воды
bool pump_started;                                              // Признак стартовавшего насоса
bool setautospeed;                                              // Признак для однократного снижения скорости насоса при паузе
bool msgfl;                                                     // Флаг для одноразовых сообщений
bool mixer_status;                                              // Статус работы мешалки
bool alarm_event;                                               // Признак срабатывания кнопки тревоги
bool acceleration_heater;                                       // Признак включенного разгонного тэна
bool send_mqtt;                                                 // Отправлять данные в облако
bool is_reboot = false;                                         // Признак перезагрузки
bool lcd_found = false;                                         // Признак наличия дисплея

//volatile float samovar_temp;                                  // Температура ESP32
volatile float bme_temp;                                        // Температура BME
volatile float start_pressure;                                  // Давление BME стартовое
volatile float bme_pressure;                                    // Давление BME
volatile float bme_prev_pressure;                               // Давление BME предыдущее значение
//float bme_humidity;                                           // Влажность
//float bme_altitude;                                           // Высота
//float bme_gas;                                                // Газ
String SamovarStatus;                                           // Текущий статус работы Самовара строкой
volatile int16_t SamovarStatusInt;                              // Текущий статус работы Самовара числом
volatile uint8_t capacity_num;                                  // Текущая позиция емкости для отбора

volatile uint8_t prev_ProgramNum;                               // Пердыдущая программа отбора
volatile uint8_t ProgramNum;                                    // Текущая программа отбора
volatile uint8_t ProgramLen;                                    // Количество строк программы отбора
volatile uint8_t WthdrwlProgress;                               // Прогресс текущего отбора
volatile int16_t startval = 0;                                  // Признак идущего отбора
volatile int currentstepcnt = 0;                                // Текущее количество шагов шагового двигателя
volatile unsigned long prev_time_ms;                            // Предыдущее время
volatile float ActualVolumePerHour;                             // Скорость отбора в литрах в моменте
volatile uint16_t CurrentStepperSpeed;                         // Скорость шагового двигателя
volatile float ActualVolumePerHour2;                             // Скорость отбора в литрах в моменте насос 2
volatile uint16_t CurrentStepper2Speed;                         // Скорость 2 шагового двигателя
volatile unsigned int CurrentStepps2;                           // Количество пройденных степпером шагов
volatile unsigned int TargetStepps2;                             // Количество шагов до нужного объема
volatile unsigned int CurrentStepps;                           // Количество пройденных степпером шагов
volatile unsigned int TargetStepps;                             // Количество шагов до нужного объема
String program_Wait_Type;                                       // Тип ожидания
unsigned long begintime;                                        // Время начала отбора
//unsigned long endtime;                                          // Время завершения отбора
unsigned long t_min;                                            // Время для паузы в секундах с момента старта ESP32
unsigned long alarm_t_min;                                      // Время для паузы в секундах для событий безопасности с момента старта ESP32
unsigned long alarm_h_min;                                      // Время для паузы в секундах для событий безопасности с момента старта ESP32
float d_s_temp_prev;                                            // Температура для определения начала кипения в режиме дистилляции
float d_s_temp_finish;                                          // Температура для определения завершения дистилляции
unsigned long d_s_time_min;                                     // Время для определения завершения дистилляции
float boil_temp;                                                // Температура куба, при которой началось кипение
float b_t_temp_prev;                                            // Температура для определения начала кипения
unsigned long b_t_time_min;                                     // Время для определения начала кипения
unsigned long b_t_time_delay;                                   // Задержка начала определения кипения
float alcohol_s;                                                // Спиртуозность, которая была при начале кипения
volatile uint16_t WFpulseCount = 0;                             // Счетчик для датчика потока
volatile uint16_t WFflowMilliLitres = 0;                        // Переменная для учета расхода воды
volatile uint16_t WFtotalMilliLitres = 0;                       // Переменная для учета расхода воды
volatile float WFflowRate;                                      // Переменная для учета расхода воды
volatile int WFAlarmCount;                                      // Переменная, считающая, сколько секунд не было подачи воды
uint16_t acceleration_temp;                                     // Счетчик для определения завершения разгона колонны
volatile float WthdrwTimeAll;                                   // Оставшееся время отбора
volatile float WthdrwTime;                                      // Время отбора текущей строки программы
String WthdrwTimeAllS;                                          // Оставшееся время отбора строкой
String WthdrwTimeS;                                             // Время отбора текущей строки программы строкой

String LogMsg;                                                  // Строка для вывода лога в javascript console
int bk_pwm;                                                     // Значение PWM насоса при работе с БК
uint32_t chipId = 0;                                            // Идентификатор ESP32
//String vr;                                                      // Причина перезагрузки ESP32
String SessionDescription;                                      // Описание параметров работы в свободном формате для сохранения в облаке
volatile float test_num_val;                                    // Тестовое численное значение
float pressure_value;                                           // Давление от датчика давления
float old_pressure_value ;                                      // старое давление для усреднения //TODO для усреднения давления
bool use_pressure_sensor;                                       // Использовать датчик давления (по результатам инициализации)
String test_str_val;                                            // Тестовое строковое значение
String Lua_status;                                              // Статус Lua
uint32_t total_byte;                                            // Доступно байт на файловой системе
uint32_t used_byte;                                             // Использовано байт на файловой системе
//uint8_t use_I2C_dev;                                            // Использовать Nano, подключенную по I2C для управления шаговым двигателем мешалки и насосом (основное назначение - пиво)
uint16_t water_pump_speed;                                      // Скорость насоса

String current_power_mode;                                      // Режим работы регулятора напряжения
volatile float target_power_volt = 0;                           // Заданное напряжение регулятора
volatile float current_power_volt = 0;                          // Текущее напряжение регулятора
unsigned long alarm_c_min;                                      // Время для ожидания возврата к заданному напряжению-1 Вольт для режима предзахлеба в секундах с момента старта ESP32
unsigned long alarm_c_low_min;                                  // Время для ожидания возврата к заданному напряжению-1 Вольт для режима предзахлеба в секундах с момента старта ESP32

volatile float prev_target_power_volt;                          // Предыдущее заданное напряжение регулятора
volatile uint16_t current_power_p;                              // Расчитанная мощность на регуляторе напряжения
uint8_t power_err_cnt;                                          // Счетчик ошибок по напряжению/мощности
#define TIME_C 4                                                // Время ожидания в минутах для программы режима предзахлеба

uint16_t MaxPower = 3000;                                       // Номинальная мощность ТЭНа

uint8_t wp_count;                                               // Переменная для расчета времени работы насоса на повышенной мощности при старте

bool BrokenFS = false;                                          // Признак поврежденной файловой системы
// Переменные для переключения между регуляторами
 static uint8_t PwrFactor=0; //множитель коррекции для различных регуляторов
 static String PwrMSG_str = "Мощность";    // название типа управления Напряжение / Мощность
 static String PwrSign = "Вт";      // Подпиcь единиц измерения В/Вт

#endif
