#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS_CLT1 2
#define ONE_WIRE_BUS_CLT2 3
#define OVERRIDE_SWITCH_PIN 4
#define FAN1_PWM_PIN 8
#define FAN2_PWM_PIN 9
#define POTENTIOMETER_PIN 16

// Define temperature thresholds
#define FAN_ON_TEMP 95
#define FAN_OFF_TEMP (FAN_ON_TEMP - 10)
#define FAN_HIGH_TEMP (FAN_ON_TEMP + 10)
#define FAN_HIGH_DUTY_CYCLE 95
#define FAN_LOW_DUTY_CYCLE 40
#define OVERRIDE_DUTY_CYCLE 60

// Define variables
float temperature1 = 0;
float temperature2 = 0;
float averageTemp = 0;
bool fanOverride = false;
int fan1DutyCycle = 0;
int fan2DutyCycle = 0;
int overrideDutyCycle = 0;

OneWire oneWire_CLT1(ONE_WIRE_BUS_CLT1);
DallasTemperature sensor_CLT1(&oneWire_CLT1);

OneWire oneWire_CLT2(ONE_WIRE_BUS_CLT2);
DallasTemperature sensor_CLT2(&oneWire_CLT2);

void setup() {
  pinMode(OVERRIDE_SWITCH_PIN, INPUT_PULLUP);
  pinMode(FAN1_PWM_PIN, OUTPUT);
  pinMode(FAN2_PWM_PIN, OUTPUT);
  // Initialize Serial for debugging
  Serial.begin(9600);
  // Initialize temperature sensors
  sensor_CLT1.begin();
  sensor_CLT2.begin();
}

void loop() {
  // Read temperatures
  temperature1 = readTemperature(sensor_CLT1);
  temperature2 = readTemperature(sensor_CLT2);

  // Calculate average temperature
  averageTemp = calculateAverageTemperature();

  // Check if temperatures are valid
  if (isValidTemperature(temperature1) && isValidTemperature(temperature2)) {
    // Determine fan duty cycle based on temperature
    calculateFanDutyCycle(averageTemp);
    // Check for override switch
    if (digitalRead(OVERRIDE_SWITCH_PIN) == LOW) {
      // Override mode
      fanOverride = true;
      overrideDutyCycle = map(analogRead(POTENTIOMETER_PIN), 0, 1023, 0, 100);
      analogWrite(FAN1_PWM_PIN, overrideDutyCycle);
      analogWrite(FAN2_PWM_PIN, overrideDutyCycle);
    } else {
      // Normal operation
      fanOverride = false;
      analogWrite(FAN1_PWM_PIN, fan1DutyCycle);
      analogWrite(FAN2_PWM_PIN, fan2DutyCycle);
    }
  } else {
    // Invalid temperatures, turn off fans
    analogWrite(FAN1_PWM_PIN, 0);
    analogWrite(FAN2_PWM_PIN, 0);
  }

  // Output temperature, fan status, and override duty cycle to serial
  Serial.print("Temperature 1: ");
  Serial.print(temperature1);
  Serial.print("°C, Temperature 2: ");
  Serial.print(temperature2);
  Serial.print("°C, Average Temperature: ");
  Serial.print(averageTemp);
  Serial.print("°C, Fan Override: ");
  Serial.print(fanOverride ? "ON" : "OFF");
  if (fanOverride) {
    Serial.print(", Override Duty Cycle: ");
    Serial.print(overrideDutyCycle);
    Serial.print("%");
  }
  Serial.println();
  delay(1000); // Adjust delay as needed
}

float readTemperature(DallasTemperature sensor) {
  sensor.requestTemperatures();
  return sensor.getTempCByIndex(0);
}

float calculateAverageTemperature() {
  return (temperature1 + temperature2) / 2;
}

bool isValidTemperature(float temp) {
  return temp >= -20 && temp <= 130;
}

void calculateFanDutyCycle(float temp) {
  if (temp >= FAN_ON_TEMP) {
    fan1DutyCycle = fan2DutyCycle = (temp >= FAN_HIGH_TEMP) ? FAN_HIGH_DUTY_CYCLE : FAN_LOW_DUTY_CYCLE;
  } else {
    fan1DutyCycle = fan2DutyCycle = 0;
  }
}
