#include <WiFi.h> //Примеры библиотеки https://developer.alexanderklimov.ru/arduino/esp32/wifi.php
#include <ESP32Time.h>
#include <PubSubClient.h>
// Wi-Fi
//const char* ssid = "********";
//const char* password = "********";
// MQTT
//https://alexgyver.ru/lessons/cstring/ Строки константы
//https://alexgyver.ru/lessons/arrays/ массивы
//https://alexgyver.ru/lessons/pointers/?ysclid=m1c98rz8gu536680849 указатели
//https://alexgyver.ru/lessons/functions/#шаблоны функции
const char* mqtt_server = "m6.wqtt.ru";
String testString = "Test string"; //String строка https://alexgyver.ru/lessons/strings/
const int mqtt_port = 11594;
const char* mqtt_user = "u_qh5xfM";
const char* mqtt_password = "ruHBifL9";
const char* num = "123";      //Для теста
const char* numf = "123.45";  //Для теста
// SENSOR
const int sending_period = 1;
const bool retain_flag = false;
const char* temperature_topic = "stend/temperature";
const char* time_topic = "stend/time";
ESP32Time rtc(10800);  // offset in seconds GMT+1
const char* ntpServer = "pool.ntp.org"; //const char* ntpServer = "ntp1.jussieu.fr";
const float BETA = 3950; // should match the Beta Coefficient of the thermistor
WiFiClient espClient;
PubSubClient client(espClient);
uint32_t tmr1;
int analogValue;
float celsius;
void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    String clientId = "ESP32-" + WiFi.macAddress();
    if (client.connect(clientId.c_str(), mqtt_user, mqtt_password) ) {
      Serial.println("connected");
      client.subscribe("stend/temperature/onoff");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}
void sendData() {
  analogValue = analogRead(34);
  //Разрешение 12 битного АЦП 4095
  celsius = 1 / (log(1 / (4095. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
  Serial.print("Temperature: ");
  Serial.print(celsius);
  Serial.println(" ℃");
  Serial.println(analogValue);
  //Serial.println(rtc.getTime("%A, %B %d %Y %H:%M:%S"));   // (String) returns time with specified format
  // formating options  http://www.cplusplus.com/reference/ctime/strftime/
  //struct tm timeinfo = rtc.getTimeStruct();
  //Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");   //  (tm struct) Sunday, January 17 2021 07:24:38
  client.publish(temperature_topic, String(celsius).c_str(), retain_flag);
  //String s = rtc.getTime("%A, %B %d %Y %H:%M:%S");
  //client.publish(time_topic, s.c_str(), retain_flag);
}
// stend/temperature/onoff
void callback(char* topic, byte* payload, unsigned int length) {
  char* cleanPayload = (char*)malloc(length + 1);
  payload[length] = '\0';
  memcpy(cleanPayload, payload, length + 1);
  String msg = String(cleanPayload);
  free(cleanPayload);
  int num = msg.toInt();
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("]: ");
  Serial.println(msg);
  if (num == 1) {
    digitalWrite(23, HIGH);
    digitalWrite(19, HIGH);
  }
  if (num == 0) {
    digitalWrite(23, LOW);
    digitalWrite(19, LOW);
  }
}
void setup() {
  Serial.begin(115200);
  pinMode(23, OUTPUT);
  pinMode(19, OUTPUT);
  digitalWrite(23, LOW);
  digitalWrite(19, LOW);
  WiFi.begin("Wokwi-GUEST", "", 6);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(250);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  /*---------set with NTP---------------*/
  configTime(0, 0, ntpServer);
  struct tm timeinfo;
  if (getLocalTime(&timeinfo)) {
    Serial.print("Сегодня ");
    Serial.print(timeinfo.tm_mday);
    Serial.println(" число");
    //Установим полученную дату в контроллер
    rtc.setTimeStruct(timeinfo);
  }
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  //Пример работы со строками константами
  /*Serial.print(strlen(mqtt_server));
  Serial.print(" символов в ");
  Serial.println(mqtt_server);
  Serial.print(strlen(testString.c_str()));
  Serial.print(" символов в ");
  Serial.println(testString);
  Serial.println("1. " + testString + " И " + mqtt_server);
  String s = "2. " + testString + " И " + mqtt_server;
  Serial.println(s);
  s = "3. " + testString + " И " + mqtt_server;
  Serial.println(s.c_str());
  int n = atoi(num);
  Serial.println(n);
  float f = atof(numf);
  Serial.println(f);*/
  delay(1500);
}
void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  if (millis() - tmr1 >= (sending_period * 1000)) {
    tmr1 = millis();
    sendData();
  }
}