<?php
class Verbraucher_1_Stufig extends IPSModule
{
    private $timerID;

    public function Create()
    {
        parent::Create();

        // Verbraucherspezifische Properties
        $this->RegisterPropertyInteger("BoilerLeistung", 6000); // Standardwert für Volllast
        $this->RegisterPropertyInteger("Mindesttlaufzeit", 4); // Standardwert für Volllast
        $this->RegisterPropertyInteger("Zeit_Zwischen_Zustandswechseln", 1);
        $this->RegisterPropertyInteger("Schaltkontakt1", 0);
        $this->RegisterPropertyInteger("Interval", 5); // Recheninterval

        // Verbraucherspezifische Variabeln
        $this->RegisterVariableBoolean("IstNacht", "IstNacht", "", 0);
        $this->RegisterVariableInteger("DailyOnTime", "DailyOnTime", "", 0);
        $this->RegisterVariableBoolean("IsTimerActive", "IsTimerActive", "", 0);

        // Verbraucherspezifischer Timer
        $this->SetValue("IsTimerActive", false);
        $this->RegisterTimer("ZustandswechselTimer",0,"IPS_RequestAction(" .$this->InstanceID .', "ResetPowerSteps", "");');

        // Variabeln für Kommunkation mit Manager
        $this->RegisterVariableInteger("Sperre_Prio", "Sperre_Prio");
        $this->RegisterVariableInteger("PV_Prio", "PV_Prio");
        $this->RegisterVariableBoolean("Idle", "Idle", "", 0);
        $this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0);
        $this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0);
        $this->RegisterVariableString("PowerSteps", "PowerSteps");
        $this->RegisterVariableInteger("Power", "Power");
        $this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving");
        $this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0);

        // Hilfsvariabeln für Idle zustand
        $this->RegisterPropertyInteger("IdleCounterMax", 2);
        $this->RegisterVariableInteger("IdleCounter", "IdleCounter", "", 0);
        $this->SetValue("IdleCounter", 0);

        // Initialisiere Idle
        $this->SetValue("Idle", true);

        $this->RegisterTimer("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');

    }

    public function ApplyChanges()
    {
        parent::ApplyChanges();
        $this->SetTimerInterval("Timer_Do_UserCalc_Verb",$this->ReadPropertyInteger("Interval")*1000); 

    }

    public function RequestAction($Ident, $Value)
    {
        switch ($Ident) {
            
            case "SetAktuelle_Leistung":
                $this->SetValue("Power", (int)$Value);
                break;
    
            case "GetCurrentData":
                $this->SetValue("Is_Peak_Shaving", (bool)$Value);
                break;

            case "ResetPowerSteps":
                $this->ResetPowerSteps($Value);
                break;

            case "Do_UserCalc":
                $this->SetAktuelle_Leistung($this->GetValue("Power"));
                $this->GetCurrentData($this->GetValue("Is_Peak_Shaving"));
                break; 

            default:
                throw new Exception("Invalid Ident");
        }
    }




    // Methode zum Setzen der PowerSteps und Timer starten
    public function SetTimerOn()
    {
        // Timer setzen, der nach "Zeit_Zwischen_Zustandswechseln" abläuft
        $zeitZwischenZustandswechseln = $this->ReadPropertyInteger(
            "Zeit_Zwischen_Zustandswechseln"
        );
        $this->SetTimerInterval(
            "ZustandswechselTimer",
            $zeitZwischenZustandswechseln * 60000
        ); // Timer in Millisekunden
        IPS_LogMessage("Verbraucher", "In Set Methode");

        // Timer-Status auf true setzen
        $this->SetValue("IsTimerActive", true);
    }

    // Methode zum Zurücksetzen von PowerSteps nach Ablauf des Timers
    public function ResetPowerSteps()
    {
        // PowerSteps wieder auf den ursprünglichen Zustand setzen (wie vorherige Funktionalität)
        $this->SetValue(
            "PowerSteps",
            json_encode([$this->GetValue("Aktuelle_Leistung")])
        );

        // Timer stoppen
        $this->SetTimerInterval("ZustandswechselTimer", 0);

        // Timer-Status auf false setzen
        $this->SetValue("IsTimerActive", false);
    }
    // Methode zum Setzen des aktuellen Stromverbrauchs
    public function SetAktuelle_Leistung(float $power)
    {
        $this->CheckIdle($power);
        if ($this->GetValue("Aktuelle_Leistung") != $power) {
            $this->SetTimerOn();
        }
        $this->SetValue("Aktuelle_Leistung", $power);
        $this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));

        $boilerLeistung = $this->ReadPropertyInteger("BoilerLeistung");
        $schaltkontaktID = $this->ReadPropertyInteger("Schaltkontakt1");

        if ($power == $boilerLeistung) {
            $schaltkontaktStatus = true;
        } elseif ($power == 0) {
            $schaltkontaktStatus = false;
        } else {
            // Keine Änderung, wenn power nicht 0 oder boilerLeistung entspricht
            return;
        }

        $currentStatus = GetValue($this->ReadPropertyInteger("Schaltkontakt1"));

        // Schaltkontaktstatus ändern
        SetValue(
            $this->ReadPropertyInteger("Schaltkontakt1"),
            $schaltkontaktStatus
        );

        if ($schaltkontaktStatus) {
            $this->SetValue("DailyOnTime", $this->GetValue("DailyOnTime") + 1);
        }
    }

    // Methode zum Abrufen der aktuellen Daten
    public function GetCurrentData(bool $Peak)
    {
        $IstNacht = $this->GetValue("IstNacht");
        $NeuesIstNacht = $this->ist_nachts();

        if ($IstNacht == true && $NeuesIstNacht == false) {
            $this->SetValue("DailyOnTime", 0);
        }

        $this->SetValue("IstNacht", $NeuesIstNacht);

        $DailyOnTime = $this->GetValue("DailyOnTime");
        $Mindestlaufzeit =
            $this->ReadPropertyInteger("Mindesttlaufzeit") * 60 * 12;

        // Überprüfen, ob der Timer aktiv ist
        if ($this->GetValue("IsTimerActive")) {
            // Timer ist aktiv, PowerSteps setzen
            $this->SetValue(
                "PowerSteps",
                json_encode([$this->GetValue("Aktuelle_Leistung")])
            );
        }
        // Wenn Nacht und Mindestlaufzeit nicht erreicht ist
        elseif ($NeuesIstNacht && $DailyOnTime < $Mindestlaufzeit) {
            if ($Peak) {
                $this->SetValue(
                    "PowerSteps",
                    json_encode([
                        0,
                        $this->ReadPropertyInteger("BoilerLeistung"),
                    ])
                );
            } else {
                $this->SetValue("PowerSteps",json_encode([$this->ReadPropertyInteger("BoilerLeistung")]));
            }
        }
        // Andernfalls
        else {
            if ($Peak) {
                $this->SetValue("PowerSteps", json_encode([0]));
            } else {
                $this->SetValue("PowerSteps",json_encode([0,$this->ReadPropertyInteger("BoilerLeistung"),])
                );
            }
        }
    }

    public function CheckIdle($power)
    {
        $lastpower = GetValue($this->GetIDForIdent("Aktuelle_Leistung"));
        if ($lastpower != $power) {
            $this->SetValue("Idle", false);
            $this->SetValue("IdleCounter",$this->ReadPropertyInteger("IdleCounterMax"));
        }
        // IdleCounter auslesen und verarbeiten
        $idleCounter = $this->GetValue("IdleCounter");
        if ($idleCounter > 0) {
            $this->SetValue("Idle", false);
            $this->SetValue("IdleCounter", $idleCounter - 1);
        } else {
            $this->SetValue("Idle", true);
        }
    }

    private function ist_nachts()
    {
        date_default_timezone_set("Europe/Berlin"); // Setze hier deine Zeitzone

        $aktuelle_zeit = strtotime(date("H:i")); // Aktuelle Zeit in Stunden und Minuten umwandeln
        $start_nacht = strtotime("22:00"); // Startzeit der Nacht (22 Uhr)
        $ende_nacht = strtotime("07:00"); // Endzeit der Nacht (7 Uhr)

        if ($aktuelle_zeit >= $start_nacht || $aktuelle_zeit < $ende_nacht) {
            return true;
        } else {
            return false;
        }
    }
}

?>
