#pragma once
#include "Samovar.h"

#ifdef USE_WATER_PUMP

#include <Arduino.h>
#include <GyverPID.h>

#ifndef PUMP_PWM_FREQ
#define PUMP_PWM_FREQ 1000
#else
#pragma message ("CUSTOM PUMP_PWM_FREQ")
#endif

static ESP32PWM pump_pwm;

// =========================
// PID
// =========================
//
static GyverPID pump_regulator(3.0, 0.03, 0.0, 1000);

// фильтр температуры
static float filtTemp = 0;

// последнее значение PWM
static float last_pwm = 100;

// скорость изменения PWM
static const float max_step = 5;

// =========================
// ИНИЦИАЛИЗАЦИЯ
// =========================
void init_pump_pwm(uint8_t pin, int freq) {

    // 8 бит PWM = 0..255
    pump_pwm.attachPin(pin, freq, 8);

    // насос охлаждает
    pump_regulator.setDirection(REVERSE);

    // диапазон работы насоса
    pump_regulator.setLimits(40, 100);

    // уставка температуры
    pump_regulator.setpoint = SamSetup.SetWaterTemp;

    pump_started = false;

    // стартовое значение
    pump_pwm.write(last_pwm);
    water_pump_speed = last_pwm;
}

// =========================
// УСТАНОВКА PWM
// =========================
void set_pump_pwm(float duty) {

    if (alarm_event) {

        water_pump_speed = 0;
        pump_pwm.write(0);
        pump_started = false;

        return;
    }

    duty = constrain(duty, 0, 255);

    // старт насоса
    if (!pump_started && duty > 0) {

        wp_count = 0;

        pump_pwm.write(PWM_START_VALUE);
        water_pump_speed = PWM_START_VALUE;

        pump_started = true;

        delay(1000);

        pump_pwm.write(duty);
        water_pump_speed = duty;

        return;
    }

    // антизалипание
    if (duty > 0 && wp_count < 10 && pump_started) {

        if (bk_pwm != PWM_LOW_VALUE * 4) {

            pump_pwm.write(bk_pwm);
            water_pump_speed = bk_pwm;

        } else {

            pump_pwm.write(PWM_START_VALUE);
            water_pump_speed = PWM_START_VALUE;
        }

        wp_count++;

        return;
    }

    if (duty == 0)
        pump_started = false;

    pump_pwm.write(duty);
    water_pump_speed = duty;
}

// =========================
// PID
// =========================
void set_pump_speed_pid(float temp) {

    // фильтр температуры
        filtTemp = filtTemp * 0.75 + temp * 0.25;

    // вход PID
    pump_regulator.input = filtTemp;

    // расчёт PID
    float pwm = pump_regulator.getResult();

    // ограничение скорости изменения PWM
    if (pwm > last_pwm + max_step)
        pwm = last_pwm + max_step;

    if (pwm < last_pwm - max_step)
        pwm = last_pwm - max_step;

    last_pwm = pwm;

    // управление насосом
    set_pump_pwm(pwm);
}

#endif