diff --git a/Int_VGT/README.md b/Int_VGT/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/Int_VGT/form.json b/Int_VGT/form.json deleted file mode 100644 index 9f5911e..0000000 --- a/Int_VGT/form.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "elements": [ - { - "type": "ValidationTextBox", - "name": "DeviceID", - "caption": "Device ID" - } - ] -} diff --git a/Int_VGT/module.json b/Int_VGT/module.json deleted file mode 100644 index afb5884..0000000 --- a/Int_VGT/module.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "{ED0ED0AC-3843-0888-DF27-FA488A5BCEF3}", - "name": "Int_VGT", - "type": 3, - "vendor": "Belevo", - "aliases": [ - "VGT MQTT-Gateway" - ], - "prefix": "VGT", - "parentRequirements": [ - "{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}" - ], - "childRequirements": [], - "implemented": [ - "{7F7632D9-FA40-4F38-8DEA-C83CD4325A32}" - ] -} diff --git a/Int_VGT/module.php b/Int_VGT/module.php deleted file mode 100644 index 538f70b..0000000 --- a/Int_VGT/module.php +++ /dev/null @@ -1,237 +0,0 @@ -RegisterPropertyString('DeviceID', ''); - - /** ------------------------------------------- - * STATUS Variablen (schreibbar) - * ------------------------------------------*/ - $this->RegisterVariableInteger('PowerProduction', 'Power Production', '', 10); - $this->EnableAction('PowerProduction'); - - $this->RegisterVariableBoolean('IsReady', 'Is Ready', '', 11); - $this->EnableAction('IsReady'); - - $this->RegisterVariableBoolean('IsRunning', 'Is Running', '', 12); - $this->EnableAction('IsRunning'); - - $this->RegisterVariableInteger('StateOfCharge', 'State of Charge', '', 13); - $this->EnableAction('StateOfCharge'); - - $this->RegisterVariableInteger('MinSOC', 'Min SOC', '', 14); - $this->EnableAction('MinSOC'); - - $this->RegisterVariableInteger('MaxSOC', 'Max SOC', '', 15); - $this->EnableAction('MaxSOC'); - - /** ------------------------------------------- - * REMOTE CONTROL (read-only) - * ------------------------------------------*/ - $this->RegisterVariableInteger('PowerSetpoint', 'Power Setpoint', '', 20); - $this->RegisterVariableString('Strategy', 'Strategy', '', 21); - - // Debug - $this->RegisterVariableString('RemoteControlPayload', 'Remote Control Payload', '', 30); - - /** ------------------------------------------- - * FEEDBACK REQUEST (read-only) - * ------------------------------------------*/ - $this->RegisterVariableString('FeedbackRequestPayload', 'Feedback Request Payload', '', 40); - - /** ------------------------------------------- - * MQTT verbinden - * ------------------------------------------*/ - $this->ConnectParent('{C6D2AEB3-6E1F-4B2E-8E69-3A1A00246850}'); - } - - public function ApplyChanges() - { - parent::ApplyChanges(); - - $this->ConnectParent('{C6D2AEB3-6E1F-4B2E-8E69-3A1A00246850}'); - - // Beim Start niemals subscriben – erst wenn Daten fließen oder Parent aktiv wird - $this->Subscribed = false; - - // Parent-Status überwachen für Re-Subscribe - $this->RegisterMessage($this->InstanceID, IM_CHANGESTATUS); - - $parent = @IPS_GetInstance($this->InstanceID)['ConnectionID'] ?? 0; - if ($parent > 0 && IPS_InstanceExists($parent)) { - $this->RegisterMessage($parent, IM_CHANGESTATUS); - } - } - - /* --------------------------------------------------------- - * MESSAGE SINK – PARENT STATUS - * ---------------------------------------------------------*/ - public function MessageSink($TimeStamp, $SenderID, $Message, $Data) - { - if ($Message === IM_CHANGESTATUS) { - - // Eigene Instanz aktiv - if ($SenderID === $this->InstanceID && ($Data[0] ?? 0) === IS_ACTIVE) { - $this->TrySubscribe(); - return; - } - - // Parent aktiv - $parent = @IPS_GetInstance($this->InstanceID)['ConnectionID'] ?? 0; - if ($parent > 0 && $SenderID === $parent && ($Data[0] ?? 0) === IS_ACTIVE) { - $this->TrySubscribe(); - return; - } - } - } - - /* --------------------------------------------------------- - * SAFE SEND TO PARENT - * ---------------------------------------------------------*/ - private function SafeSendToParent(array $packet) - { - $parent = @IPS_GetInstance($this->InstanceID)['ConnectionID'] ?? 0; - if ($parent === 0 || !IPS_InstanceExists($parent)) { - return; - } - - if (IPS_GetInstance($parent)['InstanceStatus'] !== IS_ACTIVE) { - return; - } - - @ $this->SendDataToParent(json_encode($packet)); - } - - /* --------------------------------------------------------- - * Subscribe erst ausführen, wenn Parent sicher aktiv ist - * ---------------------------------------------------------*/ - private function TrySubscribe() - { - if ($this->Subscribed) { - return; - } - - $device = $this->ReadPropertyString('DeviceID'); - if ($device === '') { - return; - } - - $this->Subscribed = true; - - $this->Subscribe("feedback-request/$device"); - $this->Subscribe("remote-control-request/$device"); - } - - /* --------------------------------------------------------- - * REQUEST ACTION - * ---------------------------------------------------------*/ - public function RequestAction($Ident, $Value) - { - $this->SetValue($Ident, $Value); - } - - /* --------------------------------------------------------- - * SUBSCRIBE (safe) - * ---------------------------------------------------------*/ - private function Subscribe(string $topic): void - { - $this->SafeSendToParent([ - 'DataID' => '{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}', - 'PacketType' => 8, - 'QualityOfService' => 0, - 'Retain' => false, - 'Topic' => $topic, - 'Payload' => '' - ]); - } - - /* --------------------------------------------------------- - * PUBLISH (safe) - * ---------------------------------------------------------*/ - private function Publish(string $topic, string $payload): void - { - $this->SafeSendToParent([ - 'DataID' => '{043EA491-0325-4ADD-8FC2-A30C8EEB4D3F}', - 'PacketType' => 3, - 'QualityOfService' => 0, - 'Retain' => false, - 'Topic' => $topic, - 'Payload' => $payload - ]); - } - - /* --------------------------------------------------------- - * RECEIVE DATA - * ---------------------------------------------------------*/ - public function ReceiveData($JSONString) - { - // Beim ersten Paket: subscriben - $this->TrySubscribe(); - - $data = json_decode($JSONString, true); - if (!is_array($data)) return; - - $topic = $data['Topic'] ?? ''; - $payload = $data['Payload'] ?? ''; - - $device = $this->ReadPropertyString('DeviceID'); - - /* --------------------------------------------------------- - * 1️⃣ FEEDBACK REQUEST - * ---------------------------------------------------------*/ - if ($topic === "feedback-request/$device") { - - $this->SetValue('FeedbackRequestPayload', $payload); - - $json = json_decode($payload, true); - if (!is_array($json)) { - $json = []; - } - - $response = array_merge($json, [ - "power_production" => $this->GetValue('PowerProduction'), - "is_ready" => $this->GetValue('IsReady'), - "is_running" => $this->GetValue('IsRunning'), - "state_of_charge" => $this->GetValue('StateOfCharge'), - "min_soc" => $this->GetValue('MinSOC'), - "max_soc" => $this->GetValue('MaxSOC') - ]); - - $this->Publish("feedback-response/$device", json_encode($response)); - return; - } - - /* --------------------------------------------------------- - * 2️⃣ REMOTE CONTROL REQUEST - * ---------------------------------------------------------*/ - if ($topic === "remote-control-request/$device") { - - $this->SetValue('RemoteControlPayload', $payload); - - $json = json_decode($payload, true); - if (is_array($json)) { - - if (array_key_exists('power_setpoint', $json)) { - $this->SetValue('PowerSetpoint', (int)$json['power_setpoint']); - } - - if (array_key_exists('strategy', $json)) { - $this->SetValue('Strategy', (string)$json['strategy']); - } - } - - $this->Publish("remote-control-response/$device", $payload); - return; - } - } -} - -?> diff --git a/VGT_Sub/form.json b/VGT_Sub/form.json index 9f5911e..7b87ce6 100644 --- a/VGT_Sub/form.json +++ b/VGT_Sub/form.json @@ -4,6 +4,80 @@ "type": "ValidationTextBox", "name": "DeviceID", "caption": "Device ID" + }, + { + "type": "Label", + "caption": "Variablen zuordnen" + }, + { + "type": "SelectVariable", + "name": "VarPowerProduction", + "caption": "Power Production Variable (Float)" + }, + { + "type": "SelectVariable", + "name": "VarStateOfCharge", + "caption": "State of Charge Variable (Float/Integer)" + }, + { + "type": "SelectVariable", + "name": "VarIsRunning", + "caption": "Is Running Variable (Boolean)" + }, + { + "type": "Label", + "caption": "SOC Bereich" + }, + { + "type": "NumberSpinner", + "name": "MinSOC", + "caption": "Min SOC", + "minimum": 0, + "maximum": 100 + }, + { + "type": "NumberSpinner", + "name": "MaxSOC", + "caption": "Max SOC", + "minimum": 0, + "maximum": 100 + }, + { + "type": "Label", + "caption": "Abonnierte Topics" + }, + { + "type": "Label", + "caption": "feedback-request/" + }, + { + "type": "Label", + "caption": "remote-control-request/" + }, + { + "type": "Label", + "caption": "Debug" + }, + { + "type": "Label", + "caption": "Alle empfangenen MQTT-Daten werden in den Debug-Log geschrieben." + } + ], + "status": [ + { + "code": 101, + "icon": "spinner", + "caption": "Verbindung wird hergestellt..." + }, + { + "code": 102, + "icon": "ok", + "caption": "Bereit" + }, + { + "code": 200, + "icon": "error", + "caption": "Fehlerhafte Konfiguration" } ] }