<?php
class WP_Steuerung extends IPSModule
{
    public function Create()
    {
        parent::Create();

        // WP-Spezifische Properies
        $this->RegisterPropertyInteger("WP_Leistung", 6000);
        $this->RegisterPropertyInteger("Wolkenschwellwert", 60);
        $this->RegisterPropertyInteger("Wolkenwert", 0);
        $this->RegisterPropertyInteger("Aussentemperatur", 0);
        $this->RegisterPropertyInteger("Referenzzeit", 0);
        $this->RegisterPropertyInteger("Sperrkontakt", 0);
        $this->RegisterPropertyInteger("Kontakt_Erhoeung", 0);
        $this->RegisterPropertyBoolean("Schwellwert_Anwenden", false);
        $this->RegisterPropertyInteger("Schwellwert", 0);
        $this->RegisterPropertyInteger("WW_Temp", 1);        
        $this->RegisterPropertyInteger("Interval", 5); // Recheninterval

        // WP-Spezifische Variabeln
        $this->RegisterVariableBoolean("Sperrzeit", "Sperrzeit", "", false);
        $this->RegisterVariableInteger("Mindestlaufzeit", "IdleCounter", "", 0);
        $this->RegisterVariableInteger("Zustand_WP", "Zustand_WP", "", 1);
        $this->RegisterVariableInteger("WP_Laufzeit_Zahler", "WP_Laufzeit_Zahler", "", 20*12);
        $this->RegisterVariableBoolean("LetzterPeakwert", "LetzterPeakwert", "", false);
        $this->RegisterVariableBoolean("LetzterPeakwert_Aenderung", "LetzterPeakwert_Aenderung", "", false);



        // 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_WP",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");');

    }

    public function ApplyChanges()
    {
        parent::ApplyChanges();
        $this->SetTimerInterval("Timer_Do_UserCalc_WP",$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 des aktuellen Stromverbrauchs
    public function SetAktuelle_Leistung(float $power)
    {
        $sperrzei_abs =
            ((60 *
                60 *
                (GetValue($this->ReadPropertyInteger("Aussentemperatur")) +
                    10)) /
                25) *
            6;

        if ($sperrzei_abs > 6 * 60 * 60) {
            $sperrzei_abs = 6 * 60 * 60;
        }
        if (
            $this->ReadPropertyInteger("Wolkenschwellwert") <
                GetValue($this->ReadPropertyInteger("Wolkenwert")) ||
            $sperrzei_abs < 0
        ) {
            $sperrzei_abs = 0;
        }
        $sperrzeit = (GetValue($this->ReadPropertyInteger("Referenzzeit")) % 86400) - $sperrzei_abs;
        $entsperrzeit = GetValue($this->ReadPropertyInteger("Referenzzeit")) % 86400;
        $aktuellezeit = time() % 86400;

        $this->CheckIdle($power);

        $its_lock_time = $this->GetValue("Sperrzeit");
        if (
            $aktuellezeit > $sperrzeit &&
            $aktuellezeit < $entsperrzeit &&
            $this->GetValue("WP_Laufzeit_Zahler") > 240
        ) {
            $this->SetValue("Sperrzeit", true);
        } elseif ($this->GetValue("WP_Laufzeit_Zahler") > 240) {
            $this->SetValue("Sperrzeit", false);
        }

        $newlocktime = $this->GetValue("Sperrzeit");

        if (
            $newlocktime == true &&
            $its_lock_time == false &&
            $this->GetValue("WP_Laufzeit_Zahler") > 240
        ) {
            $this->SetValue("WP_Laufzeit_Zahler", 0);
            SetValue($this->ReadPropertyInteger("Sperrkontakt"), true);
        } elseif (
            $newlocktime == false &&
            $its_lock_time == true &&
            $this->GetValue("WP_Laufzeit_Zahler") > 240
        ) {
            $this->SetValue("WP_Laufzeit_Zahler", 0);
            SetValue($this->ReadPropertyInteger("Sperrkontakt"), false);
        } elseif (
            $this->GetValue("Aktuelle_Leistung") != $power ||
            ($this->GetValue("WP_Laufzeit_Zahler") > 240 &&
                $this->GetValue("LetzterPeakwert") !=
                    $this->GetValue("LetzterPeakwert_Aenderung"))
        ) {
            $this->SetValue("WP_Laufzeit_Zahler", 0);

            $LastPeak = $this->GetValue("LetzterPeakwert");
            $this->SetValue("LetzterPeakwert_Aenderung", $LastPeak);
            $state = $this->GetValue("Zustand_WP");

            if ($state == 0) {
                $this->SetValue("Zustand_WP", 1);
                SetValue($this->ReadPropertyInteger("Sperrkontakt"), false);
                SetValue($this->ReadPropertyInteger("Kontakt_Erhoeung"), false);
            } elseif ($state == 1) {
                // Normalbetrieb
                if (
                    $LastPeak &&
                    $power == $this->ReadPropertyInteger("WP_Leistung")
                ) {
                    $this->SetValue("Zustand_WP", 1);
                    $this->SetValue(
                        "Aktuelle_Leistung",
                        $this->ReadPropertyInteger("WP_Leistung")
                    );
                } elseif ($LastPeak && $power == 0) {
                    $this->SetValue("Zustand_WP", 2);
                    $this->SetValue("Aktuelle_Leistung", 0);
                } elseif (
                    $LastPeak == false &&
                    $power == $this->ReadPropertyInteger("WP_Leistung")
                ) {
                    $this->SetValue("Zustand_WP", 3);
                    $this->SetValue(
                        "Aktuelle_Leistung",
                        $this->ReadPropertyInteger("WP_Leistung")
                    );
                } elseif ($LastPeak == false && $power == 0) {
                    $this->SetValue("Zustand_WP", 1);
                    $this->SetValue("Aktuelle_Leistung", 0);
                }
            } elseif ($state == 2) {
                // Sperre
                if (
                    $LastPeak &&
                    $power == $this->ReadPropertyInteger("WP_Leistung")
                ) {
                    $this->SetValue("Zustand_WP", 1);
                    $this->SetValue(
                        "Aktuelle_Leistung",
                        $this->ReadPropertyInteger("WP_Leistung")
                    );
                } elseif ($LastPeak && $power == 0) {
                    $this->SetValue("Zustand_WP", 2);
                    $this->SetValue("Aktuelle_Leistung", 0);
                } elseif (
                    $LastPeak == false &&
                    $power == $this->ReadPropertyInteger("WP_Leistung")
                ) {
                    $this->SetValue("Zustand_WP", 3);
                    $this->SetValue(
                        "Aktuelle_Leistung",
                        $this->ReadPropertyInteger("WP_Leistung")
                    );
                } elseif ($LastPeak == false && $power == 0) {
                    $this->SetValue("Zustand_WP", 1);
                    $this->SetValue("Aktuelle_Leistung", 0);
                }
            } elseif ($state == 3) {
                // Erhöht
                if (
                    $LastPeak &&
                    $power == $this->ReadPropertyInteger("WP_Leistung")
                ) {
                    $this->SetValue("Zustand_WP", 1);
                    $this->SetValue(
                        "Aktuelle_Leistung",
                        $this->ReadPropertyInteger("WP_Leistung")
                    );
                } elseif ($LastPeak && $power == 0) {
                    $this->SetValue("Zustand_WP", 2);
                    $this->SetValue("Aktuelle_Leistung", 0);
                } elseif (
                    $LastPeak == false &&
                    $power == $this->ReadPropertyInteger("WP_Leistung")
                ) {
                    $this->SetValue("Zustand_WP", 3);
                    $this->SetValue(
                        "Aktuelle_Leistung",
                        $this->ReadPropertyInteger("WP_Leistung")
                    );
                } elseif ($LastPeak == false && $power == 0) {
                    $this->SetValue("Zustand_WP", 1);
                    $this->SetValue("Aktuelle_Leistung", 0);
                }
            } else {
                $this->SetValue("Zustand_WP", 1);
            }

            $newState = $this->GetValue("Zustand_WP");

            if ($newState == 0) {
                SetValue($this->ReadPropertyInteger("Sperrkontakt"), false);
                SetValue($this->ReadPropertyInteger("Kontakt_Erhoeung"), false);
            } elseif ($newState == 1) {
                SetValue($this->ReadPropertyInteger("Sperrkontakt"), false);
                SetValue($this->ReadPropertyInteger("Kontakt_Erhoeung"), false);
            } elseif ($newState == 2) {
                SetValue($this->ReadPropertyInteger("Sperrkontakt"), true);
                SetValue($this->ReadPropertyInteger("Kontakt_Erhoeung"), false);
            } elseif ($newState == 3) {
                SetValue($this->ReadPropertyInteger("Sperrkontakt"), false);
                SetValue($this->ReadPropertyInteger("Kontakt_Erhoeung"), true);
            } else {
                SetValue($this->ReadPropertyInteger("Sperrkontakt"), false);
                SetValue($this->ReadPropertyInteger("Kontakt_Erhoeung"), false);
            }
        } else {
            $newCount = $this->GetValue("WP_Laufzeit_Zahler");
            $this->SetValue("WP_Laufzeit_Zahler", $newCount + 1);
        }

        $this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600))));
    }

    // Methode zum Abrufen der aktuellen Daten
    public function GetCurrentData(bool $Peak)
    {
        // tagessperrzeit berechnen

        $this->SetValue("LetzterPeakwert", $Peak);

        if($this->GetValue("WP_Laufzeit_Zahler")<(20*12)){

            $this->SetValue("PowerSteps", json_encode([$this->GetValue("Aktuelle_Leistung")]));

        }elseif($this->ReadPropertyBoolean("Schwellwert_Anwenden")==true && ($this->ReadPropertyInteger("Schwellwert")>GetValue($this->ReadPropertyInteger("WW_Temp"))) ){
            
            $this->SetValue("PowerSteps", json_encode([$this->ReadPropertyInteger("WP_Leistung")]));
        }
        else{
            $this->SetValue("PowerSteps", json_encode([0, $this->ReadPropertyInteger("WP_Leistung")]));
        }
    }

    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);
        }
    }
}
?>
