#include <WiFi.h> 
#include <OneWire.h>
#include <PubSubClient.h>
#include <math.h>
#include <DallasTemperature.h>

// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";

// MQTT settings
const char* mqtt_server = "mqtt.eclipseprojects.io";
const char* mqtt_topic1 = "esp32/temperature/both";

// Analog thermistor settings
const float BETA = 3950;
const int analogPin = 34;

// DS18B20 digital temperature sensor setup
const int oneWireBus = 2;
OneWire onewire(oneWireBus);
DallasTemperature sensors(&onewire); 

// Create WiFi and MQTT client objects
WiFiClient espClient;
PubSubClient client(espClient);

// Connect to WiFi
void connectWiFi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("WiFi Connected");
}

// Connect to MQTT broker
void connectMQTT() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    String clientId = "ESP32Client-" + String(random(0xffff), HEX);
    if (client.connect(clientId.c_str())) {
      Serial.println("Connected to MQTT broker");
    } else {
      Serial.print("Failed to connect, state ");
      Serial.println(client.state());
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  connectWiFi();
  client.setServer(mqtt_server, 1883);
  pinMode(analogPin, INPUT);
  sensors.begin();
}

void loop() {
  if (!client.connected()) {
    connectMQTT();
  }
  client.loop();

  // Read analog sensor
  int analogValue = analogRead(analogPin);
  float celsius = 1 / (log(1 / (4095.0 / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
  Serial.print("Analog Temp: ");
  Serial.print(celsius);
  Serial.println("℃");

  // Read digital sensor
  sensors.requestTemperatures();
  float temperatureC = sensors.getTempCByIndex(0);
  Serial.print("Digital Temp: ");
  Serial.print(temperatureC);
  Serial.println("℃");

String payload = "{\"analog\":" + String(celsius, 2) + ",\"digital\":" + String(temperatureC, 2) + "}";
client.publish("esp32/temperature/both", payload.c_str());
Serial.println("Published combined JSON payload: " + payload);

  delay(5000); // Delay between readings
}